我在获取数据并将其设置为使用useEffect和useState的功能组件中的状态时遇到问题。
我的问题是我想将axios async / await的数据提取保存在一个单独的文件中,以提高应用程序的可伸缩性,但是在不解决诺言的情况下,我不了解如何更新状态(不被拒绝) )。
特别是我正在尝试从Promise中检索状态为data的表行数组,但是我不知道如何将响应的结果设置为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响应中存在rows数组。
不幸的是,此代码无法正常工作,错误:未捕获(承诺)TypeError:无法读取未定义的属性'forEach'
我发现了另一个解决方案,它是在useEffect方法中定义promise,如下所示:
useEffect(() => {
const { id } = props.match.params;
const fetchData = async () => {
const result = await axios.get(`/api/test/${id}`);
setData(result.data.rows);
};
fetchData();
}, []);
此代码在我的应用程序中有效,但是正如我说的那样,我不希望在组件文件中包含promise,而是希望将所有promise都放在action.js中以实现应用程序可伸缩性(以防我更改URL不必更改所有文件),但在那种情况下,我不知道将 setData(result.data.rows); 放在哪里
有什么建议吗? 谢谢
答案 0 :(得分:0)
您仍然需要使用async / await。 .then()在返回值时执行,但是您的函数将继续渲染并且不会等待它。 (通过尝试以空状态访问forEach,从而使我们错误)。错误后,通过.then()的promise将更新值,这就是为什么您可以在控制台中看到它们的原因。
useEffect(() => {
async function getData() {
const { id } = props.match.params;
await props.getTableRows(id).then((res) => {
setData(res);
});
}
getData()
}, []);
此外,在访问状态之前,您可以检查空值(通常是好的做法)。
if (this.state.somestate != null) {
//Run code using this.state.somestate
}
答案 1 :(得分:0)
我看不到您从getTableRows
返回任何内容。您只是分派结果,但没有为函数调用返回res
。
如果您提供了错误跟踪信息,将会很有帮助。