useState和useEffect的使用问题
写了个自定义的数据请求hook
const useFetch = (method = "GET") => {
const [res, setRes] = useState({});
const [url, setUrl] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const firstUpdate = useRef(true);
const sendFetch = (url) => {
setUrl(getUrl(url));
};
useEffect(() => {
(async () => {
if (firstUpdate.current) return (firstUpdate.current = false);
try {
const options = {
method,
headers: { "Content-Type": "application/json;charset=utf-8" },
};
setLoading(true);
const res = await fetch(url, options);
const json = await res.json();
setLoading(false);
setRes(json.data || json);
} catch (error) {
setLoading(false);
setError(error);
}
})();
return () => {
}
}, [url]);
return { sendFetch, res, loading, error };
};
然后在组件里使用:
const StartForm = props => {
const { sendFetch, res, loading } = useFetch();
const [instockData, setInstockData] = useState({
userId: '',
fullName: '',
unitCode: '',
});
useEffect(() => {
sendFetch(`${url}?`);
},[])
}
现在的问题就是:我想等res有数据了之后去setInstockData
,所以我需要把res
作为useEffect
的依赖放到它的数组里。但是这样的话会导致死循环了,
然后我想使用useRef
来让sendFetch
只执行一次,但是感觉也麻烦,
最后我想再使用那个useLayoutHook
来监听res
的变化,然后去setInstockData
,但是这样会导致页面闪烁。
useLayoutEffect(() => {
Object.keys(res).length && setInstockData({...instockData,...res})
},[res])//这样会导致页面闪烁
有没有更好的办法呢。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你在自定义的 useFetch() 中已经将 res 设定为了一个 state,按照你的逻辑 instockData 要依赖 res,此时完全可以直接使用res即可,无需再定义另外的 state (instockData) 了。
将 instockData 看成是一个派生状态,或者类似 vue 中计算属性一样去处理。