Search code examples
reactjsredux

Correctly dispatching logout action redux-saga


I have an app with the below code to handle HTTP requests:

import { logout } from '../containers/App/actions';
import store from '../store';

/**
 * Parses the JSON returned by a network request
 *
 * @param  {object} response A response from a network request
 *
 * @return {object}          The parsed JSON from the request
 */
function parseJSON(response) {
  if (response.status === 204 || response.status === 205) {
    return null;
  }
  return response.json();
}

/**
 * Checks if a network request came back fine, and throws an error if not
 *
 * @param  {object} response   A response from a network request
 *
 * @return {object|undefined} Returns either the response, or throws an error
 */
function checkStatus(response) {
  if (response.status >= 200 && response.status < 300) {
    return response;
  }

  const error = new Error(response.statusText);
  error.response = response;
  throw error;
}

/**
 * Requests a URL, returning a promise
 *
 * @param  {string} url       The URL we want to request
 * @param  {object} [options] The options we want to pass to "fetch"
 *
 * @return {object}           The response data
 */
export default function request(url, options) {
  const headers = {
    Accept: 'application/json',
    'Content-Type': 'application/json',
    'Access-Control-Request-Headers': 'Content-Type, Authorization'
  };
  const token = localStorage.getItem('token');
  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }
  const newOptions = {
    ...options,
    mode: 'cors',
    headers
  };
  return fetch(url, newOptions)
    .then(checkStatus)
    .then(parseJSON)
    .catch(err => {
      // check for 401 here and throw an action to clean the store and logout.
      console.log(err);
      if (err.response.status === 401) {
        store.dispatch(logout);
      }
      throw err;
    });
}

Among other things, the handler checks for error codes and dispatches a LOGOUT action to clean the store and session. My logout action is defined as:

export function logout() {
  return {
    type: LOGOUT
  };
}

However, the code is not working as I want. My dispatch(logout) causes the following error: Error: Actions must be plain objects. Use custom middleware for async actions.

How could I fix this?


Solution

  • You are passing dispatch a function logout so it will show this error. You need edit like this:

    store.dispatch(logout();
    

    Update: If you want logout is an async function, you can update this function:

    function logout() {
      return async (dispatch) => {
        await logout();
    
        dispatch({
          type: LOGOUT,
        });
      };
    }
     store.dispatch(logout());