react-redux redirect to other page after login

2019-04-06 21:53发布

问题:

action.js:

export const login = creds => {
    console.log(`${url}/login`);
    const requestOptions = {
        method: "POST",
        headers: {
            Accept: "application/json",
            "Content-Type": "application/json"
        },
        body: creds
    };

    return function(dispatch) {
        dispatch({ type: LOGIN_REQUEST });
        function timer() {
            return fetch(`${url}/login`, requestOptions).then(response => {
                if (!response.ok) {
                    console.log(response);
                    return response.json().then(json => {
                        var error = new Error(json.message);
                        error.response = response;
                        throw error;
                    });
                } else {
                    console.log("3");
                    return response.json();
                }
            }).then(user => {
                if (user.message === "ok") {
                    localStorage.setItem("token", user.token);
                    dispatch({ type: LOGIN_SUCCESS, payload: user.token });
                    window.location.href = `${app}/dashboard`;
                } else {
                    const error = user.message;
                    throw new Error(error);
                }
            }).catch(function(error) {
                dispatch(loginError(error));
            });
        }
        setTimeout(timer, 5000)
    }
};

I am unable to redirect in a single-page manner to my dashboard, I searched a lot but I didn't get anything useful. I am using React Router v4. Can you please suggest whether I am doing this user login with JWT the right way or not.

回答1:

create a your own history in history.js file using this history library.

//history.js
import createHistory from 'history/createBrowserHistory'

const history = createHistory()

export default history

Supply it to your router:

<Router history = {history}>.....</Router>

Then you can use this history object to redirect from anywhere. In your action:

import history from './history'
history.push(`${app}/dashboard`)


回答2:

  1. You can add react-router-redux which will conveniently add all routing info to the Redux state, but also you can use push from react-router-redux by:

dispatch(push('/dashboard'))

You can access it by import { push } from 'react-router-redux'

  1. I think you are not doing anything wrong with JWT. I would abstract your fetch call with the helper function. I assume you need to add your access token to all future requests after authorization, and using helper function you can do it easier and keep you code cleaner.


回答3:

window.location.href will hit your server and you'll loose all the benefits of a single page application, you should use a client side routing instead with the history object

In this scenario a good solution could be pass a callback from the component that triggers the first dispatch containing a history.push to the new state

e.g.

Assuming that inside your component props you have access to history

login(body, () => {
  this.props.history.push('/dashboard');
})

then in place of window.location.href = ${app}/dashboard you invoke the callback