reactjs - 编写需要来自其他操作的数据的 redux 操作的最佳方法是什么
问题描述
我已经对可能的方法进行了一些研究,但是我找不到一种使用与我正在开发的应用程序中的架构相同的架构。例如,React 文档说我们应该有一个方法来发出 HTTP 请求,然后在不同的点(请求开始时,收到响应时等)调用操作。但我们有另一种方法。我们使用一个动作来进行 HTTP 调用,然后分派结果。更准确地说,我的用例是这样的:
// action to get resource A
getResourceA () {
return dispatch => {
const result = await axios.get('someLink');
dispatch({
type: GET_RES_A,
payload: result
});
};
}
// another action which needs data from resource A
getSomethingElseByIdFromA (aId) {
return async dispatch => {
const result = await axiosClient.get(`someLink/${aId}`);
dispatch({
type: GET_SOMETHING_BY_ID_FROM_A,
payload: result
});
};
}
如前所述,第二个动作需要来自第一个动作的数据。
现在,我知道这样做的两种方法:
- 返回第一个动作的结果
getResourceA () {
return async dispatch => {
const result = await axios.get('someLink');
dispatch({
type: GET_RES_A,
payload: result
});
return result;
};
}
// and then, when using it, inside a container
async foo () {
const {
// these two props are mapped to the getResourceA and
// getSomethingElseByIdFromA actions
dispatchGetResourceA,
dispatchGetSomethingElseByIdFromA
} = this.props;
const aRes = await dispatchGetResourceA();
// now aRes contains the resource from the server, but it has not
// passed through the redux store yet. It's raw data
dispatchGetSomethingElseByIdFromA(aRes.id);
}
但是,我现在正在处理的项目希望数据首先通过商店——以防它必须被修改——只有在那之后,它才能被使用。这让我想到了第二种做事方式:
- 创建一个“聚合”服务,并
getState
在操作完成后使用该方法访问状态。
aggregateAction () {
return await (dispatch, getState) => {
await dispatch(getResourceA());
const { aRes } = getState();
dispatch(getSomethingElseByIdFromA(aRes.id));
};
}
然后在容器中简单地调用这个动作。
我想知道第二种方法是否可以。我觉得仅仅为了在整个操作中访问它们而在 redux 商店中拥有东西并不好。如果是这种情况,那么解决这个问题的更好方法是什么?
解决方案
我认为拥有/使用Epic
fromredux-observable
将最适合您的用例。在以相同的逻辑处理它们之前,它会先让动作通过你的减速器(与上面提到的方法不同)。此外,使用动作流可以让您在整个数据流中操纵数据,而不必存储不必要的东西。反应式编程和可观察模式本身在异步操作方面有一些很大的优势,这是一个比 redux-thunk、sagas 等 imo 更好的选择。
推荐阅读
- spring - 异常:rg.springframework.cloud.gcp.data.datastore.core.mapping.DatastoreDataException:无法将类 PageRequest 转换为 Datastore
- elasticsearch - ElasticSearch 异常是什么意思:“所有分片失败”和“未找到 id 的搜索上下文”?
- python - 使用 Pandas 提取配置文件(看起来像 K/V 但不是)
- python - 如何比较两个列表中的项目并根据结果创建一个新列表?
- android - GestureDetector 不适用于 Android PdfViewer lib
- ansible - 无法使用 Ansible 调整logical_volume 的大小
- azure - 如何删除 Azure DevOps 中的共享步骤?
- express - 使用 Apollo 联邦实现的 Apollo-server-express
- swift - 如何计算 iPad 上非全屏页面工作表视图的大小
- bash - 为什么来自 PS1 的函数调用需要转义?