reactjs - 在 redux 存储中的状态更改和相应的反应状态更改之间进行交互的正确方法
问题描述
我有一个反应应用程序,它使用 redux 状态管理工具以及本地本机状态管理,即反应(组件/容器)状态。假设有一个表单组件,其数据存储在反应状态。API 调用是通过 sagas 进行和处理的,它会相应地更新 Redux Store。如何更改反应状态,例如将表单状态键更改为loading: false
或通常在 saga 从 API 调用接收数据后如何使用数据更新表单(受控表单或不受控)。对于受控表单,将有一个容器组件来管理该表单的道具,但又如何更新容器的状态呢?我不想将数据存储在 redux 和 react 状态,特别是如果该数据用于本地存储,而不是 redux 存储
如果我使用该getDerivedStateFromProps
方法,我将需要将该数据存储在例如 reduxState 中,以便最终复制或计算并放入反应状态。我现在正在使用下面描述的方法,但我想知道你们还有什么可以建议的。
https://github.com/redux-saga/redux-saga/issues/907
我正在使用的示例代码如下,类似于链接中描述的代码
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 的优势:处理异步副作用。您的示例代码通过在回调函数中使用 Promise 来绕过 redux-saga 的好处。没有什么能阻止你使用 redux-saga 和 redux thunk 或基于 promise 的回调,但你必须权衡是否值得(或需要)在项目中使用多种方法来处理异步副作用。
您似乎在处理几个问题。
一个问题是 redux 存储和组件状态中的数据重复。
我不想将数据存储在 redux 和 react 状态,特别是如果该数据用于本地存储,而不是 redux 存储
你指的是什么数据?
如果您指的是实际的服务器负载,那么将服务器负载存储在 redux 存储中并让 react-redux 在 redux 状态更改时更新组件是非常常规的。这是 redux 所基于的单向数据流。
如果您的意思是“派生”数据(可以从服务器负载推断的数据),那么我建议不要在 redux 存储和组件状态中复制这些数据。建议仅在 redux 存储中存储所需的最少量数据 - 否则您会遇到一致性问题以及维护/更新相同数据的多个副本。您可以查看redux 数据规范化器或选择器(例如重新选择)来处理此问题。 Redux 的文档对这些概念有很好的解释。
由于您使用的是本地组件状态,那么也许您可能会查看react 的 context API,它可以作为 redux 状态管理的替代方案。我一直在使用具有本地组件状态的上下文 api,但通常我的使用仅限于真正的“临时/短暂”UI 状态(例如,是否显示/隐藏弹出窗口)。我没有尝试(或不需要)使用 react 的上下文来绕过 redux-saga/react-redux ,就像上面的示例代码一样。
祝你好运 :)
推荐阅读
- r - 使用棒球的日期返回错误
- content-security-policy - CSP 标头指令问题
- r - 将两个命名向量/矩阵相乘,应用 n-gram 模型 (stringdist::qgrams)
- r - 如何使用 Leaflet(R 中)平滑地从一个点平移/缩放到另一个点?
- python - 我有 10 个测试模块,每个模块包含一个测试用例。如何在 Pytest POM 框架中使用测试用例名称为每个测试用例生成日志文件?
- javascript - Javascript 用数组值替换字符串 $n
- windows - 保存的 Word 文档打开为空白文档(已解决)
- reactjs - Hide 键盘导航 react-native
- visual-studio-code - 如何为 VSCode (tmlanguage.json) 自定义这个语法高亮的主题?
- javascript - 无法在 Joomla 网站中添加亚马逊横幅链接