【问题标题】:Error: Actions must be plain objects. Use custom middleware for async actions in redux错误:操作必须是普通对象。在 redux 中使用自定义中间件进行异步操作
【发布时间】:2018-01-02 14:49:18
【问题描述】:

下面是我的动作创建者的代码:

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

      };
  }

在输入旁边:FETCH_POSTS,如果我添加 , 而不是 ;我收到错误意外令牌。这是动作创建者的语法吗?

如果我用 ; 替换编译时出现错误“操作必须是纯 Javascript 对象。

知道为什么吗?

【问题讨论】:

标签: redux react-redux


【解决方案1】:

GibboK 的回答已经指出语法错误。

但是,我认为您不了解正确使用操作。你跑:

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

这是在创建一个承诺。您当前正在一个操作中返回它。 Reducers 是确定性和无副作用的,因此为什么操作应该是普通的 JS 对象。你不应该提交承诺。

相反,您应该使用一些相关的中间件,例如redux-thunkredux-saga 或其他。当实际的承诺解决后,您应该发送一个操作。

作为一个简单的人为示例,使用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})
        });
};

请注意,此代码只是一个示例,不一定适合在生产系统中使用。

【讨论】:

    【解决方案2】:

    当您将 , 替换为 ; 时,您会收到错误消息,因为如您的错误消息所述,操作必须返回一个 JavaScript 对象。

    在 JavaScript 对象属性中应该用, 分隔为:

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

    这样return 语句将返回一个具有两个属性typepayload 的新对象。

    【讨论】:

      【解决方案3】:

      根据 redux 文档:

      Actions 是纯 JavaScript 对象。操作必须有一个type property,它指示正在执行的操作的类型。类型 通常应定义为string constants。一旦你的应用是 足够大,您可能希望将它们移动到单独的模块中。

      和动作创建者

      动作创建者是创建动作的函数

      在 Redux 中,动作创建者只需返回一个动作:

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

      因此,当您通过 dispatch 从组件调用 action creator 时,您的操作创建者只需要简单地返回一个普通的 javascript 对象。

      所以一个普通的动作创建者将是

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

      现在,如果您想在动作创建器中调用 API,则需要在创建商店时使用 redux-thunkredux-saga 等中间件

      喜欢

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

      您使用中间件配置您的商店,您可以将您的操作修改为

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

      根据 redux-thunk 文档

      为什么需要 redux-thunk?

      Redux Thunk middleware 允许您编写动作创建者 返回一个函数而不是一个动作。 thunk 可用于延迟 一个动作的dispatch,或dispatch,仅当某个 条件满足。内部函数接收存储方法 dispatch and getStateparameters

      【讨论】:

        猜你喜欢
        • 2018-01-30
        • 2020-11-05
        • 2019-12-26
        • 2021-11-04
        • 2020-04-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多