如何获取数据并在usefeft()中使用它?
我尝试从 API 中获取数据并设置数据状态,但当我在子组件中使用数据时,我收到
[Unhandled promise rejection: TypeError: null is not an object (evaluating 'data.name')]
警告。
以下是我正在尝试执行的操作的要点。有人知道为什么会发生这种情况吗?我认为这是因为没有从 API 收到数据。我尝试添加“isLoading”状态,并且仅在其为 false 时返回 ChildComponent,但我仍然收到相同的警告(这可能是因为 useEffect 中的 setNewProp 在从 API 收到数据时没有更新)。
const ParentComponent = (props) => {
const [data, setData] = useState(null);
const [newProp, setNewProp] = useState();
const fetchData = async () => {
new DataService.retrieveData().then((response) => {
setData(response);
}
}
useEffect(() => {
fetchData();
setNewProp({ data, ...props });
}, []);
return (
<ChildComponent newProp={newProp} />
);
}
您不能在 useEffect 生命周期事件中使用异步函数。作为一个好的解决方案,我建议充分利用 useEffect 钩子并将其用作更新数据的效果。
const ParentComponent = (props) => {
const [data, setData] = useState(null);
const [newProp, setNewProp] = useState();
const fetchData = async () => {
new DataService.retrieveData().then((response) => {
setData(response);
}
}
useEffect(() => {
fetchData();
}, []);
useEffect(() => {
setNewProp({ data, ...props });
}, [data]);
return (
<ChildComponent newProp={newProp} />
);
}
我还想指出,useEffect 在第一次渲染之后运行。这意味着您的 ChildComponent 将始终收到“undefined”作为第一个 props,因为没有设置初始值:
const [newProps, setNewProp] = useState(); // initial value comes here to prevent errors
看起来您可能错过了
useEffect()
中所需的
await
,以使代码等到提取完成:
之前:
useEffect(() => {
fetchData();
setNewProp({ data, ...props });
}, []);
之后:
useEffect(() => {
(async () => {
await fetchData();
setNewProp({ data, ...props });
})();
}, []);
请注意,
useEffect()
不支持异步函数(因为它需要返回值为清理函数或未定义。例如,请参阅
这篇文章
。
但更好的可能是这样的:
const [data, setData] = useState(null);
const fetchData = async () => {
new DataService.retrieveData().then((response) => {
setData(response);
}
}
fetchData();
if (data) {
const newProp = { data, ...props };
}
在您的代码中,您首先调用 fetchData 函数,该函数在完成时会调用 useState 钩子。由于 useState 钩子异步工作,因此状态
data
不会立即更改。
useEffect(() => {
fetchData(); // Called setData()
setNewProp({ data, ...props }); // At this point, data hasn't changed yet.
}, []);
因此,您可以再次使用 useEffect 钩子来监视
data
状态的变化。然后,您应该设置
newProp
的新状态。
useEffect(() => {
(async () => {
await fetchData();
})();
}, []);
useEffect(() => {
setNewProp({...props, data });
}, [data]);