1
votes

GET requests canceling fine in this example:

export default function Post (props) {
  const _cancelToken = axios.CancelToken.source()

  useEffect(() => {
    const _loadAsyncData = async () => {
      await axios.get('/post'), { cancelToken: _cancelToken.token })
    }

    _loadAsyncData()

    return () => {
      _cancelToken.cancel()
    }
  }, [])
  return ()
}

But when I need save form via POST request, my code looks like:

export default function Form (props) {
  const _cancelToken = axios.CancelToken.source()
  const _zz = { qq: 'QQ' }

  const handleCreate = async e => {
    e.preventDefault()

    _zz.qq = 'ZZ'

    await axios.post('/form'), {}, { cancelToken: _cancelToken.token })
  }

  useEffect(() => {
    return () => {
      console.log(_zz.qq)
      _cancelToken.cancel()
    }
  }, [])

  return ()
}

Request not cancel and my _zz.qq always 'QQ' instead 'ZZ'. It's working fine without hooks, but I like hooks and want to use hooks for new components.

I want to cancel request when componentWillUnmount.

1
What if you put _cancelToken.cancel in the dependencies array useEffect(....., [_cancelToken.cancel])?Teneff
seems as expected, you unmount component and thus awaiting on axios.post gets cancelled and your _zz.qq = 'ZZ' dont seem to run as such.Rikin
Teneff, it's cancel immediately after request init (but it's works), and I thinks it's right. I need cancel when component unmount not when token changing.Gabriel
Rikin, I not sure that I understand you. _zz.qq not changed outside useEffect. I need to cancel request when component unmounting.Gabriel

1 Answers

5
votes

This is because you're losing the changes between renders. During the handleCreate call the variable changes only for that render. When the useEffect is run on a subsequent render/unmounting, you're resetting _zz to { qq: 'QQ' }. In order to get around this you need to use references.

export default function Form (props) {
  const cancelToken = useRef(null)
  const zz = useRef({ qq: 'QQ' })

  const handleCreate = async e => {
    e.preventDefault()

    cancelToken.current = axios.CancelToken.source() 
    zz.current = { qq: 'ZZ' }

    await axios.post('/form'), {}, { cancelToken: cancelToken.current.token })
  }

  useEffect(() => {
    return () => {
      console.log(zz.current) //this should now be {qq : 'ZZ'}
      if (cancelToken.current) {
        cancelToken.current.cancel()
      }
    }
  }, [])

  return null
}