'React hooks abort fetch post

when i submit my login form, i get a memory leak warning message when i set my authentication context with response data dispatch({type: "SET_AUTH", payload: responseJson}). 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.

type SigninState<T> = {
        loading: boolean,
        error?: string,
        data?: T
    }

const Signin: React.FunctionComponent = () => {
    const { dispatch } = useAuthContext()

    const defaultValue = {
        email: '',
        password: ''
    }

    const signinDefaultState = {
        loading: false,
        error: undefined,
        data: undefined
    }


    const [signinState, signinSetState] = useState<SigninState<any>>(signinDefaultState)
    const [validFormData, setValidFormData] = useState(defaultValue)


    const validFormCallback = () => {
        setValidFormData(values)
    }

    const { values, errors, handleChange, handleKeyup, handleSubmit } = useForm(
        defaultValue,
        validFormCallback,
        validate,
    )

    
    useEffect(() => {
        const abortController = new AbortController()

        if (validFormData.email !== "") {
            const postSignin: any = async () => {
                const options = {
                    ...authJsonHeader,
                    method: "POST",
                    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: "SET_AUTH", payload: responseJson})
                    //signinSetState({...signinState, loading: false, data: responseJson})
                } catch (err: any) {
                    if (!abortController.signal.aborted) {
                        signinSetState({...signinState, loading: false, error: err})
                    }
                }
            }
            postSignin()
        }
        return () => abortController.abort()

    }, [validFormData])


    return (
        <form>
            <div>
                <InputField
                    id="email"
                    label="Email"
                    type="email"
                    name="email"
                    value={values.email}
                    onKeyUp={handleKeyup}
                    onChange={handleChange}
                    error={(errors as any).email}
                />
            </div>
            <div>
                <InputField
                    id="password"
                    label="Password"
                    type="password"
                    name="password"
                    value={values.password}
                    onKeyUp={handleKeyup}
                    onChange={handleChange}
                    error={(errors as any).password}
                />
            </div>
            <div style={{ marginTop: "20px" }}>
                <Button type="primary" onClick={handleSubmit}>Sign In</Button>
                {signinState.error && <InfoBlockStyled>{signinState.error as any}</InfoBlockStyled>}
                {signinState.loading && <LoadingInline />}
            </div>
        </form>
    )
}

const InfoBlockStyled = styled(InfoBlock)(({ theme }) => ({
    marginTop: theme.spacer.m,
}))

export default Signin


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source