title: React hooks abort fetch post
body: <p>when i submit my login form, i get a memory leak warning message when i set my authentication context with response data <code>dispatch({type: &quot;SET_AUTH&quot;, payload: responseJson})</code>. I tried to abort the asynchronous request using abortController but can't fix this warning. Thanks for your help, this issue is driving me crazy.</p>
  <pre><code>type SigninState&lt;T&gt; = {
          loading: boolean,
          error?: string,
          data?: T
      }
  
  const Signin: React.FunctionComponent = () =&gt; {
      const { dispatch } = useAuthContext()
  
      const defaultValue = {
          email: '',
          password: ''
      }
  
      const signinDefaultState = {
          loading: false,
          error: undefined,
          data: undefined
      }
  
  
      const [signinState, signinSetState] = useState&lt;SigninState&lt;any&gt;&gt;(signinDefaultState)
      const [validFormData, setValidFormData] = useState(defaultValue)
  
  
      const validFormCallback = () =&gt; {
          setValidFormData(values)
      }
  
      const { values, errors, handleChange, handleKeyup, handleSubmit } = useForm(
          defaultValue,
          validFormCallback,
          validate,
      )
  
      
      useEffect(() =&gt; {
          const abortController = new AbortController()
  
          if (validFormData.email !== &quot;&quot;) {
              const postSignin: any = async () =&gt; {
                  const options = {
                      ...authJsonHeader,
                      method: &quot;POST&quot;,
                      body: JSON.stringify(validFormData),
                  } as any
                  try {
                      signinSetState({...signinState, loading: true})
                      const response = await fetch(`${process.env.REACT_APP_API_HOST}/signin`, { ...options, signal: abortController.signal })
                      const responseJson = await response.json()
                      if (!response.ok) {
                          throw responseJson
                      }
                      dispatch({type: &quot;SET_AUTH&quot;, payload: responseJson})
                      //signinSetState({...signinState, loading: false, data: responseJson})
                  } catch (err: any) {
                      if (!abortController.signal.aborted) {
                          signinSetState({...signinState, loading: false, error: err})
                      }
                  }
              }
              postSignin()
          }
          return () =&gt; abortController.abort()
  
      }, [validFormData])
  
  
      return (
          &lt;form&gt;
              &lt;div&gt;
                  &lt;InputField
                      id=&quot;email&quot;
                      label=&quot;Email&quot;
                      type=&quot;email&quot;
                      name=&quot;email&quot;
                      value={values.email}
                      onKeyUp={handleKeyup}
                      onChange={handleChange}
                      error={(errors as any).email}
                  /&gt;
              &lt;/div&gt;
              &lt;div&gt;
                  &lt;InputField
                      id=&quot;password&quot;
                      label=&quot;Password&quot;
                      type=&quot;password&quot;
                      name=&quot;password&quot;
                      value={values.password}
                      onKeyUp={handleKeyup}
                      onChange={handleChange}
                      error={(errors as any).password}
                  /&gt;
              &lt;/div&gt;
              &lt;div style={{ marginTop: &quot;20px&quot; }}&gt;
                  &lt;Button type=&quot;primary&quot; onClick={handleSubmit}&gt;Sign In&lt;/Button&gt;
                  {signinState.error &amp;&amp; &lt;InfoBlockStyled&gt;{signinState.error as any}&lt;/InfoBlockStyled&gt;}
                  {signinState.loading &amp;&amp; &lt;LoadingInline /&gt;}
              &lt;/div&gt;
          &lt;/form&gt;
      )
  }
  
  const InfoBlockStyled = styled(InfoBlock)(({ theme }) =&gt; ({
      marginTop: theme.spacer.m,
  }))
  
  export default Signin
  </code></pre>