Error: Actions must be plain objects. Use custom middleware for async actions in redux

前端 未结 3 1717
遇见更好的自我
遇见更好的自我 2021-01-22 20:04

Below is the code for my action creator:

export function fetchPosts()
  {
    const request = axios.get(`${ROOT_URL}/posts${API_KEY}`);
    return
      {
               


        
相关标签:
3条回答
  • 2021-01-22 20:44

    When you replace , with ; you get an error because, as stated by your error message, an action must return a JavaScript object.

    In JavaScript object properties should be separated by , as:

    return
          {
            type: FETCH_POSTS, // use comma here
            payload: request   
          };
    

    In this way the return statement will return a new object with two properties type and payload.

    0 讨论(0)
  • 2021-01-22 20:57

    As per redux documentation:

    Actions are plain JavaScript objects. Actions must have a type property that indicates the type of action being performed. Types should typically be defined as string constants. Once your app is large enough, you may want to move them into a separate module.

    And Action Creators

    Action creators are functions that create actions

    In Redux action creators simply return an action:

    function addTodo(text) {
      return {
        type: ADD_TODO,
        text
      }
    }
    

    So when you call the action creator from your component through dispatch your action creator just needs to simply return a plain javascript object.

    So a normal action creator will be

    export function fetchPosts()
      {
    
        return
          {
            type: FETCH_POSTS;
            payload: "somevalue"
    
          };
      }
    

    Now if you want to call APIs within your action creators you need to make use of middlewares like redux-thunk or redux-saga while creating a store

    like

    import thunk from 'redux-thunk';
    const store  = createStore(reducers, applyMiddleware(thunk));
    

    You you configure your store with middleware you can modify your actions to

    export function fetchPosts() {
        return (dispatch) =>  {   
            axios.get(`${ROOT_URL}/posts${API_KEY}`)
                   .then((response)=> {
                         dispatch( {
                               type: FETCH_POSTS,
                               payload: request
    
                         })
                    })  
            } 
    
         }
    

    As per the redux-thunk documentation

    Why Do you need redux-thunk?

    Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. The inner function receives the store methods dispatch and getState as parameters.

    0 讨论(0)
  • 2021-01-22 21:07

    GibboK's answer has already pointed out the syntax error.

    However, I don't think you understand using actions properly. You run:

    const request = axios.get(`${ROOT_URL}/posts${API_KEY}`);
    

    This is creating a promise. You are currently returning this in an action. Reducers are meant to be deterministic & side effect free, hence why actions should be plain JS objects. You should not be submitting a promise.

    Instead, you should be using some relevant middleware, e.g. redux-thunk, redux-saga or something else. You should send an action when the actual promise has resolved.

    As a simple contrived example, using redux-thunk:

    export const fetchPosts = () => (dispatch) => {
        // Send action to notify request started. Reducers often want to
        // update the state to record that a request is pending, e.g. for
        // UI purposes.
        dispatch({type: FETCH_POSTS_START});
    
        // Start request
        request = axios.get(`${ROOT_URL}/posts${API_KEY}`)
           .then(res => { 
              // Successfully received posts, submit response data
              dispatch({type: FETCH_POSTS_COMPLETE, payload: res.data})
            })
           .catch(err => { 
              // API call failed, submit error
              dispatch({type: FETCH_POSTS_ERROR, payload: err})
            });
    };
    

    Note this code is just an example and not necessarily suitable for use in a production system.

    0 讨论(0)
提交回复
热议问题