React Redux is not working as expected with Next.js & NodeJS

Viewed 2347

I'm working on an app using Next.js with redux by following this example and here is some part of store.js

// REDUCERS
const authReducer = (state = null, action) => {
    switch (action.type){
        case actionTypes.FETCH_USER:
            return action.payload || false;
        default:
            return state;
    }
}

export const rootReducer = combineReducers({
    user: authReducer,
    form: reduxForm,
});

// ACTIONS
export const fetchUser = () => {
    return (dispatch) => {
        axios.get('/api/current_user')
            .then(res => dispatch({
                type: actionTypes.FETCH_USER, 
                payload: res.data
            }));
    };
};

export const submitLogin = (values) => async dispacth => {
    const res = await axios.post('/api/login', values);

    // Router.push('/');
    // console.log(res)

    dispacth({ type: actionTypes.SUBMIT_LOGIN, payload: res.data });
};

and the client side such as header

function mapStateToProps (state) {
    const { user } = state
    return { user }
}

export default connect(mapStateToProps)(Header)

and when I console.log('############=>', this.props.user); the props & I'm not loggesd in then it's showing null but showing some extra data such as below screenshot

enter image description here

but when I logged in & console.log('############=>', this.props.user); it's showing proper data without extra data such as below image

enter image description here

what I'm doing wrong? please help me. Thanks

3 Answers

The problem is probably not on your React / Redux code but on your Next.js routes.

You’re trying to call an API with axios.get('/api/current_user') but Next.js is giving you an HTML response, that you indeed store in authReducer extracting it as action.payload.

You probably want to see this section about Custom Server and Routing.

dispacth({ type: actionTypes.SUBMIT_LOGIN, payload: res.data });

Should be:

dispatch({ type: actionTypes.SUBMIT_LOGIN, payload: res.data });

@MunimMunna is spot on. Your server is either redirecting you to an HTML login page, or returning an HTML error page for failed creds. In either case, Axios is seeing a 200 status code, so it thinks the response is valid. Your action creator blindly fires off the action with the HTML payload attached.

Consider making these changes:

  • Client:

    • Add a catch block to your axios promise that logs failed response.
    • Pass an Accept header of application/json to tell the server you don't want HTML responses. If you are lucky, this might be enough to get NextJS to behave the way you want.
  • Server: If needed, change the server to detect whether the request is an XHR request, or if application/json is the only response type the client wants. Don't redirect if those conditions are true. Return return a 401 status code instead. You can optionally return a JSON body with some extra error information.

Related