【发布时间】:2020-12-04 11:21:33
【问题描述】:
我在使用 useEffect 和 useState 获取数据并将它们设置为功能组件中的状态时遇到问题。
我的问题是我想通过 axios async/await 在单独的文件中完成数据获取,以提高应用程序的可扩展性,但是我不明白如何更新状态以防承诺得到解决(不是被拒绝)。
特别是我试图从 promise 中检索一个名为 data in state 的表行数组,但我不知道如何在 state 中设置响应的结果
这是组件文件中的代码:
const [data, setData] = React.useState([]);
useEffect(() => {
const { id } = props.match.params;
props.getTableRows(id).then((res) => {
setData(res);
});
//or is it better:
//props.getTableRows(id).then(setData); ?
}, []);
还有我的 action.js:
export const getTableRows = (id, history) => async (dispatch) => {
try {
const res = await axios.get(`/api/test/${id}`);
dispatch({
type: GET_TEST,
payload: res.data.rows,
});
} catch (error) {
history.push("/test");
}
};
在上图中可以看到action.js中调用的promise response里面的rows数组是存在的。
不幸的是,这段代码不起作用,错误:Uncaught (in promise) TypeError: Cannot read property 'forEach' of undefined
我找到了另一种解决方案,即在 useEffect 方法中定义承诺,如下所示:
useEffect(() => {
const { id } = props.match.params;
const fetchData = async () => {
const result = await axios.get(`/api/test/${id}`);
setData(result.data.rows);
};
fetchData();
}, []);
此代码在我的应用程序中运行,但正如我所说,我不喜欢在组件文件中包含承诺,而是希望它们在 action.js 中为应用程序可扩展性提供所有承诺(以防 url 更改我不'不必更改所有文件)但在这种情况下,我不知道将 setData(result.data.rows); 放在哪里,这在最后一个示例中似乎是正确的选择
有什么建议吗? 谢谢
【问题讨论】:
-
你仍然需要使用 async/await。 .then() 在返回值时执行,但是您的函数将继续渲染并且不会等待它。 (通过尝试在 null 状态下访问 forEach 导致它出错)
标签: reactjs promise use-effect use-state