I have the following code:
const getAllSlidersUrl = "a url";
const adminID = "an admin id";
const adminlogintoken="a token";
const SliderContainer = () => {
const [allSlides, setAllSlides] = useState([]);
useEffect(
() => {
axios.post(
getAllSlidersUrl,
{
adminid: adminID,
token: adminlogintoken
}
)
.then(
(response) => {
setAllSlides(response.data);
}
)
.catch(
(error) => {
alert(error);
}
)
}, []
);
return (
//I have a button here
//when I press button it executes the following:
{
allSlides.map(
item =>
<div key={item.slider_id} style={{ paddingTop: "10px", paddingBottom: "10px" }}>
<SliderComponent
adminId={adminID}
adminLoginToken={adminlogintoken}
sliderID={item.slider_id}
sliderImage={item.slider_image}
sliderEnText={item.slider_en_text}
sliderArText={item.slider_ar_text}
sliderEnButtonText={item.slider_en_button_text}
sliderArButtonText={item.slider_ar_button_text}
sliderEnButtonLink={item.slider_en_button_link}
sliderArButtonLink={item.slider_ar_button_link}
deleteSliderOnClick={deleteSliderHandler}
updateSliderToAllSlides={updatingSliderHandler}
/>
</div>
)
}
);
}
When I login to the page and press F12 (to give me the inspect tab),sometimes everything is fine and I get no warning but most of the times I get the following warning:
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
and whenever this warning is present and I press the button the application breaks and I get error: allSlides.map is not a function
I tried adding return () => {}
at the end of the useEffect
hook, I also tried changing useEffect
to the following:
useEffect(
() => {
let isSubscribed = true;
axios.post(
getAllSlidersUrl,
{
adminid: adminID,
token: adminlogintoken
}
)
.then(
(response) => {
if(isSubscribed){
setAllSlides(response.data);
}
}
)
.catch(
(error) => {
alert(error);
}
)
return () => {isSubscribed = false}
}, []
);
But in both cases where I tryied to resolve the error, it doesn't resolve it.
Note that for whatever reason (in all 3 cases) sometimes the web application doesn't break and everything works fine, but most of the times I do get the warning and then the error if I press the button.
Check the reponse data type if it is of array type or not because the error states that map is not a function
that means allSlides
is not an array.
About the warning
try using ref to cancel fetch like this:
const cancelFetch = React.useRef(false);
useEffect(
() => {
axios.post(
getAllSlidersUrl,
{
adminid: adminID,
token: adminlogintoken
}
)
.then(
(response) => {
if(cancelFetch.current){
return;
}
setAllSlides(response.data);
}
)
.catch(
(error) => {
alert(error);
}
)
return () => {cancelFetch.current = true;}
}, []
);
A better way to cancel is using abort controller but this can do too. If the warning is still there then maybe another component (parent) is getting unmounted.