Changing state on redux-saga causes infinite loop inside component

I am trying to redirect user after successful login but changing state in saga is causing an infinite loop.

In my component I am using useSelector to listen to changes in isValidSession from store. If isValidSession changes to true, I want to redirect user to another page. However, when isValidSession is changed, my component keeps re-rendering in an infinite loop.

component

import { Link, useLocation } from 'react-router-dom'
import { Redirect } from 'react-router'

import MainLayout from '../../../layouts/MainLayout'
import { Typography, Alert, Row, Col, Divider } from 'antd'
import LoginForm from './LoginForm'

import { useDispatch, useSelector } from 'react-redux'
import * as loginActions from './Login.action'

const { Title } = Typography

export default function Login() {

    const dispatch = useDispatch()

    const { isValidSession, error } = useSelector((state) => state.login)

    const location = useLocation()

    let { from } = location.state || { from: { pathname: '/templates' } }

    const handleLogin = ({ email, password }) =>
        {
            dispatch(loginActions.authenticate({ email, password }))
        }

    const getAPIError = (error) =>
        error.status == 401
            ? 'Invalid username or password'
            : 'Something went wrong'

    if (isValidSession) return <Redirect push to={from.pathname} />

    return (
        <MainLayout>
            <Row align='stretch' className='vh-100'>
                <Col xs={24} md={12} lg={10} xl={8} xxl={6} className='bg--white'>
                    <div className='d-flex align-items-center h-100 p-5'>
                        <div id='login' className='w-100'>
                        
                            <Title level={3}>Welcome Back!</Title>

                            {/* ERROR MESSAGE */}
                            {error ? (
                                <Alert
                                    message={getAPIError(error)}
                                    showIcon
                                    type='error'
                                    className='mb-2'
                                />
                            ) : (
                                ''
                            )}

                            {/* FORM */}
                            <LoginForm onFinish={handleLogin} />

                            <Divider />

                            {/* ADDITIONAL LINKS */}
                            <div className='text-center'>
                                <p>
                                    Don't have an account yet?{' '}
                                    <Link
                                        to={{ pathname: '/register', state: { from: location } }}
                                    >
                                        Sign up
                                    </Link>
                                </p>
                                <Link
                                    to={{
                                        pathname: '/auth/recover-password',
                                        state: { from: location },
                                    }}
                                >
                                    Forgot your password?
                                </Link>
                            </div>
                        </div>
                    </div>
                </Col>
            </Row>
        </MainLayout>
    )
}

In my reducer, for action types.LOGIN_SUCCESS, I am making isValidSession to true.

reducer

const loginReducer = (state = initialState, action) => {
    switch (action.type) {
        case types.LOGIN_REQUESTING: {
            return {
                ...state,
                submitted: false,
            }
        }
        case types.LOGIN_SUCCESS: {
            return {
                ...state,
                submitted: true,
                successful: true,
                isValidSession: true,
            }
        }
        case types.LOGIN_ERROR: {
            const { error } = action
            return {
                ...state,
                error,
                submitted: false,
                successful: false,
                isValidSession: false,
            }
        }
        case types.UPDATE_LOGIN_CREDENTIAL: {
            const { login } = action
            return {
                ...state,
                login: {
                    ...state.login,
                    ...login,
                },
            }
        }
        case types.IS_LOGGINGIN: {
            const { isLoggingIn } = action
            return {
                ...state,
                isLoggingIn,
            }
        }
        default:
            return {
                ...state,
            }
    }
}

In my saga code, you can see that I am doing yield put({ type: types.LOGIN_SUCCESS }) to change isValidSession to true. 

saga

function* authenticateSage(payload) {
    try {
        alert('authenticateSage')

        const response = yield call(authService.login, payload.login)
        const { profile, account } = response

        yield put({ type: types.LOGIN_SUCCESS })
    } catch (error) {
        yield put({
            type: types.LOGIN_ERROR,
            error: { status: error.status, message: error.data?.message },
        })
    }
}

export default function* watchAuthentication() {
    yield takeLatest(types.LOGIN_REQUESTING, authenticateSage)
}