【react hook】react hook报错:Can‘t perform a React state update on an unmounted component...

Problem Description

In the project, I jumped to another page before the network request returned, and found that the console reported an error Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
written as follows:

  useEffect(() => {
    
    
    const getData = async() => {
    
    
      try {
    
    
        const resp: any = await fetch('/api/xxx')
        setData(resp)
      } catch(error) {
    
    
        console.log(error)
      }
    }
    getData()
  }, [])

Interpretation

The English error above tells us that status updates cannot be performed on unloaded components, which means that there is a memory leak in the application.
Because the user performs a page jump before the request returns, and the current component is uninstalled after the jump. After unloading, the request service returns the response data. At this time, the code after await (that is, setData) is executed to update the status of the component. However, the component has been unloaded at this time, so the console will throw an error.

solution

method one

  useEffect(() => {
    
    
  	let isUnMount = false
    const getData = async() => {
    
    
      try {
    
    
        const resp: any = await fetch('/api/xxx')
        // 判断当前组件有没有被卸载
        if (isUnMount) return
        setData(resp)
      } catch(error) {
    
    
        console.log(error)
      }
    }
    getData()
    return () => {
    
     isUnMount = true } // 通过给useEffect返回一个可执行的回调函数,当组件卸载时,会执行此回调设置isUnMount = true
  }, [])

Method Two

When there are a lot of requests, it is naturally inappropriate to write code redundantly in this way. Let’s look at the second method (define a useEffect at the top level, and do not perform other operations, only return a callback to useEffect to ensure priority execution)

const isUnMount = useRef(false) // 使用useRef来同步当前的卸载状态

useEffect(() => {
    
    
	return () => {
    
     isUnMount.current = true } // 通过给useEffect返回一个可执行的回调函数,当组件卸载时,会执行此回调设置isUnMount = true
}, [])

useEffect(() => {
    
    
    const getDataAaa = async() => {
    
    
      try {
    
    
        const resp: any = await fetch('/api/aaa')
        // 判断当前组件有没有被卸载
        if (isUnMount.current) return
        setDataAaa(resp)
      } catch(error) {
    
    
        console.log(error)
      }
    }
    getDataAaa()
}, [])

useEffect(() => {
    
    
    const getDataBbb = async() => {
    
    
      try {
    
    
        const resp: any = await fetch('/api/bbb')
        // 判断当前组件有没有被卸载
        if (isUnMount.current) return
        setDataBbb(resp)
      } catch(error) {
    
    
        console.log(error)
      }
    }
    getDataBbb()
}, [])

Guess you like

Origin blog.csdn.net/hzxOnlineOk/article/details/129752629
Recommended