'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 |
|---|
