Gabriel
Gabriel

Reputation: 459

Cancel Axios post request outside useEffect hook

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.

Upvotes: 1

Views: 2611

Answers (1)

Jake Luby
Jake Luby

Reputation: 1758

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
}

Upvotes: 5

Related Questions