reactjs - 在钩子中使用异步数据初始化 useReducer
问题描述
首先,一些背景。
我有一个异步加载数据的功能组件。
const { error, loading, data, getAllData } = useData(); // useData is a custom hook abstracting Context API
if (error) return <Error error={error} />;
if (!data || loading) return <LinearProgress />;
{/* etc .. */}
所以data
是异步加载的,这意味着它最初是未定义的,但是当异步加载完成时,它会获得一些真正的价值。
现在我需要在表格中显示数据,对于表格,我想将一些逻辑抽象到一个钩子中。
所以我最终有
const { error, loading, data, getAllData } = useData();
const tableCtrl = useTable(data);
if (error) return <Error error={error} />;
if (!data || loading) return <LinearProgress />;
在useTable.ts
我有
export function useTable(initialItems: TableItem[]): TableCtrl {
const [state, dispatch] = React.useReducer(reducer, {
items: initialItems,
selectedItems: [],
allSelected: false
});
return {
...state,
deleteItem: (itemToDelete: TableItem) =>
dispatch({ type: 'delete_item', item: itemToDelete }),
selectAll: () => dispatch({ type: 'select_all' }),
selectNone: () => dispatch({ type: 'select_none' }),
select: (item: TableItem) => dispatch({ type: 'select', item }),
deselect: (item: TableItem) => dispatch({ type: 'deselect', item })
};
}
现在我很确定你可以发现问题,但是initialData
钩子用来创建它的useReducer
是undefined
它并且它从来没有真正更新它。因此,当真实数据“到达”时,它不会更新钩子的状态。
我该如何解决这个问题?
解决方案
这是个有趣的问题。因为 hook ofReact.useReducer
只取初始值一次,那么它会保持状态本身,而不需要再次设置值。
所以这个想法很简单。您只需在dispatch
每次data
更改时通过导出的功能再次设置您的状态。这是想法片段:
让我们创建一个导出函数来更新您的状态useTable.ts
:
return {
setData: data => dispatch(/* This is where you set your state again */)
}
现在调用setData
您data
在主文件中所做的更改:
const { setData, ...others } = useTable(data);
React.useEffect(() => {
if (data) {
// This will sync your state with the latest data
setData(data);
}
}, [data])
推荐阅读
- python - 根据其他模型Django的值更改模型的值
- c++ - 使用柯南构建 libjpeg/9d 时引导生成文件片段时出错
- python-3.x - 使用for循环不计算列表的长度,而是计算列表中字符串的字符?
- php - PHP继承非类对象的属性
- python - Python venv 项目随机无法找到 python3 二进制文件
- sql - oracle 为在 1 分钟内出售的商品选择日期
- python-3.x - ConnectionError 异常单独工作但不能在函数中使用
- java - 在 Eclipse 中运行 Java Maven 应用程序时出现 LifecycleException
- ruby-on-rails - bundler 报告的 Gem 不兼容性没有逻辑意义
- converse.js - Notification Group Room 消息不显示未读消息,仅显示浏览器通知