【问题标题】:changing redux state from axios call back从 axios 回调更改 redux 状态
【发布时间】:2018-01-10 14:28:49
【问题描述】:

在对服务器进行 AJAX 处理后,我试图从 reducer 更改 redux 的状态,但由于某种原因,当我在 promise 响应中更改状态变量时,它仍然没有像我想要的那样更改状态。

我为 AXIOS 开发了自己的界面:

export function my_post(url, json_data, success_callback, error_callback) {
  return axios({
    method: 'post',
    url: url,
    data: btoa(JSON.stringify(json_data)) || {},
    headers: {
      'X-XSRFToken': getCookie('_xsrf')
    }
  }).then(response => {
    if (success_callback)
      success_callback(response)
  }).catch(error => {
    if (error_callback)
      error_callback(error)
  })
}

我在 reducer 中这样调用这个函数:

export default (state = initState, action) => {
    switch(action.type) {
        case actionTypes.AJAX:
            my_post(
                '/ajax/url',
                {
                    content: 'some content'
                },
                (response) => {
                    state = {
                        ...state,
                        ts: response['ts']
                    }
                }
            )
            break
    }
    return state
}

也试过这个:

export default (state = initstate, action) => {
    switch(action.type) {
        case actionTypes.AJAX:
            my_post(
                '/ajax/url',
                {
                    content: 'some content'
                }
            ).then(
                state = {
                    ...state,
                    ts: response['ts']
                }
            )
            break
    }
    return state
}

但是当我到达 return state 时,ts 参数不存在。

我在这里错过了什么?

【问题讨论】:

  • 问题是您试图在减速器内部执行异步操作。该动作应该发生在一个动作中,然后在完成时调用reducer。请阅读这篇文章,了解为什么 Redux Stores 只支持同步数据流:stackoverflow.com/questions/34570758/…

标签: reactjs redux react-redux axios


【解决方案1】:

您的提议似乎不是 redux 的标准实现。

典型的结构是调用动作,然后当动作完成一个事件并且数据被分派到所有reducer。监听减速器决定事件是否适用于它,然后适当地更改其数据。然后将这些数据返回到 UI 并需要从 state 映射到组件的 props。

对于您的代码,这意味着应该将 axios 调用作为操作调用。当调用成功或不成功返回时,应该分派一个事件,reducer 接收该事件,并使用来自事件数据的数据重组数据。

任何严肃的数据处理或思考都不应该发生在 reducer 中。 reducer 应该只是从 action 中消费数据。

我在我的 Github 上有一个简单实现的示例:https://github.com/NickDelfino/nextjs-with-redux-and-cloud-firestore

它并不完美,但显示了我上面讨论的概念。

我也认为你可能需要使用 Redux-Thunk 来做你想要的网络调用。文档和代码可以在这里找到: https://github.com/gaearon/redux-thunk

我还建议在他们的网站上阅读 redux 基础知识:https://redux.js.org/docs/basics/

欢迎提出更多问题!我希望这会有所帮助!

【讨论】:

    【解决方案2】:

    API 调用应该发生在您的操作中。您可以在 redux 操作中使用额外的包来实现异步副作用。看看redux-thunkredux-saga。但是@SteveB 是对的。您的减速器永远不会有任何副作用。他们应该是纯洁的。 From the redux docs:

    你应该永远不要在 reducer 中做的事情:

    • 改变其参数;
    • 执行 API 调用和路由等副作用 过渡;
    • 调用非纯函数,例如Date.now() 或 Math.random()。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-10
      • 1970-01-01
      • 1970-01-01
      • 2022-01-27
      • 2020-09-04
      • 1970-01-01
      • 2019-02-20
      相关资源
      最近更新 更多