'How to use useEffect properly to validate wether mounted or not mounted yet?
I have problem regarding Warning: Can't perform a React state update on an unmounted component. Every time I press and select on my select option I always get this yellow warning prompt on my mobile screen.
I read some articles that this error found on my useEffect but I don't know how to trace this error warning inside on my useEffect. Can you help me guys to solve this kind of problem?
Here is what I have on my codes:
const mountedRef = true;
const HandleGetRegion = () => {
dispatch(RegionList()).then((response) => {
if(mountedRef) setRegionList(response?.payload)
});
}
const HandleGetProvince = (id) => {
dispatch(ProvinceList(id)).then((response) => {
if(mountedRef) setProvinceList(response?.payload)
});
}
const HandleGetCity = (id) => {
dispatch(CityList(id)).then((response) => {
if(mountedRef) setCityList(response?.payload)
});
}
useEffect(() => {
HandleGetRegion();
HandleGetProvince();
HandleGetCity();
return () => {
mountedRef.current = false;
}
}, [])
Here is what my selection look like
<View style={{ flexDirection: 'row', flex: 1, flexWrap: 'wrap', alignItems: 'flex-start' }}>
<View style={{ width: '50%', padding: 3 }}>
<Text style={{ fontSize: 12, marginTop: 10 }}>Region</Text>
<Select
accessibilityLabel="Region"
placeholder="Region"
placeholderTextColor="#000"
color="#000"
mt={1}
name="pickup_region"
selectedValue={values.pickup_region}
onBlur={handleBlur('pickup_region')}
onValueChange={(itemValue) => {
setFieldValue("pickup_region", itemValue);
HandleGetProvince(itemValue);
}}
>
{
regionList && regionList?.data ? (
regionList.data?.map((data, i) => {
return (
<Select.Item key={i} label={data.name} value={data.id.toString()} />
)
})
) : <Select.Item label="No Region Available" value="" />
}
</Select>
{(errors.pickup_region && touched.pickup_region) &&
<Text style={styles.errorText}>{errors.pickup_region}</Text>
}
</View>
<View style={{ width: '50%', padding: 3 }}>
<Text style={{ fontSize: 12, marginTop: 10 }}>Province</Text>
<Select
accessibilityLabel="Province"
placeholder="Province"
placeholderTextColor="#000"
color="#000"
mt={1}
selectedValue={values.pickup_province}
onBlur={handleBlur('pickup_province')}
name="pickup_province"
onValueChange={(itemValue) => {
setFieldValue("pickup_province", itemValue);
HandleGetCity(itemValue);
}}
>
{
provinceList && provinceList?.data ? (
provinceList.data?.map((data, i) => {
return (
<Select.Item key={i} label={data.name} value={data.id.toString()} />
)
})
) : <Select.Item label="No Provinces Available" value="" />
}
</Select>
{(errors.pickup_province && touched.pickup_province) &&
<Text style={styles.errorText}>{errors.pickup_province}</Text>
}
</View>
Error:
Solution 1:[1]
While it has been planning to remove from warnings entirely, I am seeing that you are initializing mountedRef
with const
which is not correct.
Usually such typical flow should be the following checking whether if component is mounted,
// Create a custom hook so that you avoid repetition
import { useCallback, useEffect, useRef } from 'react'
function useIsMounted() {
const isMounted = useRef(false)
useEffect(() => {
isMounted.current = true
return () => {
isMounted.current = false
}
}, [])
return useCallback(() => isMounted.current, [])
}
export default useIsMounted
// Usage of hook
function Child() {
const [data, setData] = useState('loading')
const isMounted = useIsMounted()
// simulate an api call and update state
useEffect(() => {
yourApiCall().then((data) => {
if (isMounted()) setData(data)
})
}, [isMounted])
return <p>{data}</p>
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Tarik |