在 redux store 中的状态变化和相应的反应状态变化之间相互通信的正确方法

Proper way to intercommunicate between state change in redux store and corresponding react state change

我有一个 React 应用程序,它使用 redux 状态管理工具以及本地本机状态管理,即 React (component/container) 状态。 假设有一个表单组件,其数据存储在反应状态中。 API 调用是通过 sagas 进行和处理的,相应地更新 Redux Store。我如何更改反应状态,例如将表单状态键更改为 loading: false 或者通常如何在 saga 从 API 调用接收数据后用数据更新表单(受控表单或非受控表单)。对于受控表单,将有一个容器组件来管理该表单的道具,但又如何更新容器的状态呢? 我不想将数据存储在 redux 和 react 状态中,特别是如果该数据用于本地存储,而不是 redux 存储

如果我使用 getDerivedStateFromProps 方法,我将再次需要将该数据存储在例如 reduxState 中,以便最终复制或计算并放入反应状态。 我现在正在使用下面描述的方法,但我想知道你们是否还有其他任何建议。

https://github.com/redux-saga/redux-saga/issues/907

我使用的示例代码如下,与link

中描述的类似
validate = (drops, senderDetails, revalidate) => {
    const { largestLCU, actions: { validateDispatch } } = this.props
    const promise = new Promise(resolve => validateDispatch(drops, senderDetails,
      requestBatchSize, defaultMaxCapPerStop, defaultMarkerColor, largestLCU, resolve, revalidate))
    promise.then(({ success, data }) => {
      if (success) {
        this.setState((state) => {
          const { messages } = this.props
          return {
            ...state,
            senderDetails: {
              ...state.senderDetails,
              ...data,
            },
            currentStatus: {
              ...state.currentStatus,
              isAllValid: messages.length === 0,
              isFileSelected: false,
            },
            csvFile: null,
            loading: false,
          }
        })
      } else {
        this.setState({
          loading: false,
        })
      }
    })
  }

validateDispatch 调度一个动作,redux saga 拦截,执行 Api 调用并返回某些数据以在 Promise 解决后更新反应状态。当然这是妥协

一般来说,我认为您希望利用 redux-saga 的优势:处理异步 side-effects。您的示例代码通过在回调函数中使用承诺来绕过 redux-saga 的好处。没有什么能阻止你使用 redux-saga 和 redux thunk 或基于承诺的回调,但你必须权衡是否值得(或需要)在你的项目中有多种处理异步 side-effects 的方法。

您似乎在处理几个问题。

一个问题是 redux 存储和组件状态中的数据重复。

I dont want to store the data in both redux and react state, especially if that data is meant to be for local store, not redux store

你指的是什么数据?

如果您指的是实际的服务器负载,那么将服务器负载存储在 redux 存储中并让 react-redux 在 redux 状态更改时更新组件是非常传统的做法。这是 redux 所基于的 uni-directional 数据流。

如果您指的是 "derived" 数据(可以从服务器负载推断出的数据),那么我建议不要在 redux 存储和组件状态中复制此数据。建议只在 redux 存储中存储所需的最少数据量 - 否则你 运行 会陷入一致性问题和 maintaining/update 相同数据的多个副本。您可以查看 redux data normalizers or selectors (e.g. reselect) to handle this. Redux's docs 对这些概念有很好的解释。

既然您使用的是本地组件状态,那么也许您可以研究一下 react's context API,它可以作为 redux 状态管理的替代方案。我一直在使用具有本地组件状态的上下文 api,但通常我的用法仅限于真正的 "temporary/ephermeral" UI 状态(例如,弹出窗口是否为 shown/hidden)。我没有尝试(或需要)使用 React 的上下文来绕过 redux-saga/react-redux,就像上面的示例代码一样。

祝你好运:)