Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirect react router with redux-saga

I have redux-saga which should redirect user to main page after successfully logging. I do not use react-router-redux or smth like that so my router is not connected to state.

Here is my Login component

const AdminLogin: React.FC<RouteComponentProps> = ({history}) => {
    const [form, setForm] = useState({username: '', password: ''});
    const user = useSelector(getAdminUser);
    const dispatch = useDispatch();
    const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        dispatch(makeLoginAsync(form));
    };

    useEffect(() => {
        if (user && user.token) {
            history.push('/admin/main'); // here it is
        }
    }, [user, history]);


    return (
        <form onSubmit={handleSubmit} className="admin-login">
            // FORM HTML CODE
        </form>
    );
};

export default withRouter(AdminLogin);

Notice I'm dispatching form to Action, then Saga is listening my Action and does all logic and effects. I thought it would be much better to do redirection in Saga code. But I couldn't?

After successful login, Reducer changes the state sets user auth token. If I have token, I take it as user is logged in and redirect him to another page.

As you see, I implement this logic directly in the component (using Selector). But I find it very ugly.

Actually, I can access history object only in component (if component is wrapped with withRouter).

If I used react-router-redux, I could do something like

import { push } from 'react-router-redux'

and use push function to redirect from Saga. I'm new to React and I heard that it's not obligatory to connect router to redux. Also I don't want to make my application more complex and have another dependency to implement such basic feature as redirection.

So now I have to make it even more complex and implicitly. Maybe I have missed something?

Any help is welcome.

like image 694
Богдан Мельниченко Avatar asked Nov 06 '22 14:11

Богдан Мельниченко


1 Answers

pass history with dispatch event and then use it to push route inside redux

const AdminLogin: React.FC<RouteComponentProps> = ({history}) => {
    const [form, setForm] = useState({username: '', password: ''});
    const user = useSelector(getAdminUser);
    const dispatch = useDispatch();
    const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
        e.preventDefault();
        dispatch(makeLoginAsync({form,history}));
    };

    useEffect(() => {
        if (user && user.token) {
            history.push('/admin/main'); // here it is
        }
    }, [user, history]);


    return (
        <form onSubmit={handleSubmit} className="admin-login">
            // FORM HTML CODE
        </form>
    );
};

export default withRouter(AdminLogin);
like image 169
Smit Vora Avatar answered Nov 15 '22 07:11

Smit Vora