我创建了一个自定义挂钩useFetch
,该钩子返回fetch
函数,我可以在其他组件中使用。它使用承诺在里面获取一些数据。我的目标是清理使用此自定义挂钩的组件,如果要清理未决的承诺。
我该怎么做?我尝试了使用useRef
的一些东西,但还没有成功。仍获取Can't perform a React state update on an unmounted component.
警告。
const useFetch = (url) => {
const [isFetching, setIsFetching] = useState(false)
const handler = useRef(null)
useEffect(() => () => {
if (handler.current !== null) {
handler.current.cancel()
}
}, [])
return (options) => {
handler.current = window.fetch(url, options)
setIsFetching(true)
return handler.current.then(() => {
handler.current = null
setIsFetching(false)
})
}
}
export default () => {
const fetchData = useFetch('www.tld')
useEffect(() => {
fetchData({}).then(() => console.log('done'))
}, [])
return null
}
请注意,此示例中的承诺可以通过.cancel()
取消(因此在这里不是问题(。
返回cancel()
作为钩子从钩子中返回的回调。那将由消费者制止:
const useFetch(url) {
const [isFetching, setIsFetching] = useState(false)
const handler = useRef(null)
function run(options) {
handler.current = window.fetch(url, options)
setIsFetching(true)
...
}
function cancel() {
if(handler.current) {
handler.current.cancel()
}
}
return {run, cancel}
}
...
function OtherComponent({userId}) {
const [userData, setUserData] = useState(null);
const {run, cancel} = useFetch(`/user/${userId}`);
useEffect(() => {
run(options).then(setUserData);
return cancel; // it's up to consumer code to stop request
}, [userId]);
}