错误:操作必须是普通对象。在redux中使用自定义中间件进行异步操作

时间:2017-07-27 04:04:35

标签: redux react-redux

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

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

      };
  }

键入:FETCH_POSTS,如果我添加,而不是;我得到错误意外的令牌。这是动作创作者的语法吗?

然后如果我替换,用;在编译时我得到错误'动作必须是普通的Javascript对象。

知道为什么吗?

3 个答案:

答案 0 :(得分:2)

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

但是,我不认为你理解正确使用行动。你跑:

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

这是在创造一个承诺。您目前正在执行此操作。减速器意味着确定性和安全性。副作用自由,因此为什么动作应该是普通的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})
        });
};

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

答案 1 :(得分:0)

使用<ul> <li class="grade"> <a><i class="fa fa-star fa-fw">(icon goes here)</i></a> My Text </li> </ul> <a class="grade"> Text here should be white </a>替换,时会出现错误,因为正如您的错误消息所述,操作必须返回一个JavaScript对象。

在JavaScript中,对象属性应以;分隔为:

,

这样return { type: FETCH_POSTS, // use comma here payload: request }; 语句将返回一个包含两个属性returntype的新对象。

答案 2 :(得分:0)

根据 redux 文档:

  

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

动作创作者

  

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

     

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

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

因此,当您通过action creator从组件中调用dispatch时,您的操作创建者只需返回一个简单的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