取消Axios在外部使用后的发布请求

时间:2019-08-12 14:36:00

标签: reactjs axios react-hooks use-effect

在此示例中,GET请求取消正常:

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 ()
}

但是当我需要通过POST请求保存表单时,我的代码如下:

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 ()
}

请求不会取消,我的_zz.qq总是'QQ'而不是'ZZ'。没有钩子,它可以正常工作,但是我喜欢钩子,并希望将钩子用于新组件。

我想在componentWillUnmount时取消请求。

1 个答案:

答案 0 :(得分:2)

这是因为您丢失了渲染之间的更改。在handleCreate调用期间,变量仅针对该渲染更改。在后续渲染/卸载上运行useEffect时,会将_zz重置为{ qq: 'QQ' }。为了解决这个问题,您需要使用参考。

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
}