title: React Context custom middleware instead of Redux
body: <p>I think about getting rid of <code>redux</code> in my applications and make only use of the react context api. Therefor I need to have kind of a middleware to handle HTTP requests (similar to <code>redux-saga</code>). What I wrote is the following, but I am not sure if this is really a good approach:</p>
  
  <p>Here is my Context + Reducer:</p>
  
  <pre class="lang-js prettyprint-override"><code>export const initialState = {
      isAuthenticated: false,
      user: null,
      token: null,
    };
  
  export const reducer = (state, action) =&gt; {
      switch (action.type) {
          case "LOGIN":
              localStorage.setItem("user", JSON.stringify(action.payload.user));
              localStorage.setItem("token", JSON.stringify(action.payload.token));
              return {
                  ...state,
                  isAuthenticated: true,
                  user: action.payload.user,
                  token: action.payload.token
              }
          case "LOGOUT":
              localStorage.clear();
              return {
                  ...state,
                  isAuthenticated: false,
                  user: null,
                  token: null
              }
          case "TEST":
              console.log("works")
              break
          default:
              return state;
      }
  }
  
  export const AuthContext = React.createContext()
  </code></pre>
  
  
  
  <p>any the middleware i wrote:</p>
  
  <pre class="lang-js prettyprint-override"><code>export const applyApiMiddleware = dispatch =&gt; action =&gt; {
      dispatch(action)
  
      switch (action.type) {
          case "TEST":
              console.log("test")
              dispatch({
                  type: 'TEST',
                  payload: {
                      data: "foo"
                  }
              })
              break
          case "REQUEST_GET_USERS":
              fetch('/users', {
                  method: 'GET'
              })
              .then(res =&gt; dispatch({
                  type: 'REQUEST_GET_USERS_SUCCESS',
                  payload: res.data
              }))
              .catch(error =&gt; console.warn(error))
              break
          default:
              console.log("DEFAULT")
          //....
      }
  }
  </code></pre>
  
  
  
  <p>And my app.js:</p>
  
  <pre class="lang-js prettyprint-override"><code>export const App = (props) =&gt; {
      const [state, dispatch] = React.useReducer(reducer, initialState);
      const Routes = props.routes
      const apiDispatch = applyApiMiddleware(dispatch)
      return (
          &lt;AuthContext.Provider value={{state, apiDispatch}}&gt;
              &lt;div className="container"&gt;
                  &lt;div className="row"&gt;
                      &lt;div className="col-4"&gt;
                          {props.title}
                      &lt;/div&gt;
                      &lt;div className="col-4"&gt;
                      &lt;/div&gt;
                      &lt;div className="col-4"&gt;
                      &lt;/div&gt;
                  &lt;/div&gt;
                  &lt;Routes history={history}/&gt;
                  {!props.authenticated ? &lt;Redirect to="/login" push /&gt; : ''}
              &lt;/div&gt;
          &lt;/AuthContext.Provider&gt;
      )    
  }
  </code></pre>
  
  
  
  <p>I now call actions like so:</p>
  
  <pre><code>const { apiDispatch } = React.useContext(AuthContext)
  
  apiDispatch({
      type: "TEST"
  })
  </code></pre>
  
  <p>It seems to work fine and in the way I expected but what are your suggestions? One problem I think about is how could a apply multiple middlewares this way? I also somehow miss something like a <code>next()</code> call (which seems to be mandatory for multiple middlewares).</p>