我创建了一个自定义钩子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()
取消(因此,这不是问题)。
答案 0 :(得分:0)
从挂钩中返回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]);
}