如何确保React中调用第三个Hook前数据已准备就绪?
解决方法
你可以通过以下几种方式实现useGetSomeStuff等待data2就绪后执行的需求:
1. 在useGetSomeStuff内部处理未就绪的data2
直接修改useGetSomeStuff,当传入的data2未就绪时,返回默认值或暂停核心逻辑:
export const useGetSomeStuff = (data2) => { const [stuff, setStuff] = useState(null); useEffect(() => { // 仅当data2存在且加载完成、无错误时执行逻辑 if (!data2) return; const fetchStuff = async () => { const result = await someApiCall(data2); setStuff(result); }; fetchStuff(); }, [data2]); return { stuff }; };
原Hook中的调用无需修改,useGetSomeStuff会自动在data2就绪后触发逻辑。
2. 用React Query的依赖查询键包装useGetSomeStuff
如果useGetSomeStuff本质是数据请求,可将其改造为基于React Query的useQuery,把data2作为查询键的一部分,React Query会自动在data2有值时才发起请求:
export const useGetSomeStuff = (data2) => { return useQuery({ queryKey: ['someStuff', data2], queryFn: async () => { // 此时data2已就绪,直接执行请求逻辑 return await fetchSomeStuff(data2); }, // 仅当data2存在时启用查询 enabled: !!data2, }); };
原Hook调用时,useGetSomeStuff会在data2就绪后才执行查询,避免空值导致的错误。
3. 状态中转配合非Hook逻辑(仅适用于非Hook场景)
如果无法修改useGetSomeStuff且它是纯函数而非自定义Hook,可在useGetValues中用状态保存就绪后的data2,再通过useMemo触发逻辑:
export const useGetValues = () => { const [state1, setState1] = useState<string>(''); const [state2, setState2] = useState<boolean>(false); const { data: data1, isLoading: isLoadingData1, isError: isError1, } = useQueryData1(); const { data: data2, isLoading: isLoadingData2, isError: isError2, } = useQueryData2(); const [readyData2, setReadyData2] = useState(null); useEffect(() => { if (data2 && !isLoadingData2 && !isError2) { setReadyData2(data2); } }, [data2, isLoadingData2, isError2]); // 仅当readyData2存在时执行纯函数逻辑 const stuff = useMemo(() => { if (!readyData2) return null; return getSomeStuffSync(readyData2); }, [readyData2]); ... };
注意:若useGetSomeStuff是自定义Hook,此方法无法直接使用(React禁止条件调用Hook),因此更推荐前两种方案。
内容的提问来源于stack exchange,提问作者user2403607
相关产品推荐
相关产品推荐

