'Cleanup Function is not running in useEffect in React Redux
I have two dispatch actions 1. fetchHomepage and 2. removeHomepage. I want to run removeHomepage action when I click other link on header menu. So I added removeHomepage in Cleanup Function in useEffect but my cleanup function is not running. When I change something and save then it runs. I am using Redux in this React project. Please can anybody help me out.
HEADER COMPONENT -
import React, { useEffect, useState } from "react";
import "./header.css";
import { useDispatch, useSelector } from "react-redux";
import {
fetchHomepage,
removeHomepage,
} from "../../redux/actions/HomepageActions";
import { setBgColor } from "../../redux/actions/HomepageActions";
import { Link } from "react-router-dom";
import { useLocation } from "react-router-dom";
import Skeleton from "../other/skeletons/Skeleton";
const Header = () => {
const dispatch = useDispatch();
const isLoading = useSelector((state) => state.homepageReducer.isLoading);
const header = useSelector((state) => state.homepageReducer.data.navLinks);
const bgColor = useSelector((state) => state.homepageReducer.bgColor);
const { bgColour, borderColor, iconColor } = bgColor;
const product = useSelector((state) => state.addToCartReducer.products);
const { pathname } = useLocation();
const location = pathname;
console.log("component loaded");
useEffect(() => {
console.log("useffect ran");
const changeNavBg = (bgColor) => {
if (window.scrollY > 0) {
dispatch(setBgColor(bgColor));
} else {
dispatch(
setBgColor({
bgColour: "bg-transparent",
borderColor: "",
iconColor: "",
})
);
}
};
window.addEventListener("scroll", () => {
changeNavBg({
bgColour: "bg-black",
borderColor: "border-white",
iconColor: "text-white",
});
});
dispatch(fetchHomepage());
return () => {
console.log("cleanup function ran");
dispatch(removeHomepage());
window.removeEventListener("scroll", changeNavBg);
};
}, []);
if (isLoading) {
return <Skeleton header={"header"} />;
}
return (
<>
<h1>HEADER</h1>
{
<div className="dvHeader">
<nav
className={`navbar navbar-expand-lg ${bgColour} ${
location !== "/" ? "bg-black" : ""
} navbar-light fixed-top`}
>
<div className="container">
<div>
<button
className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#slideDownMenu"
aria-controls="slideDownMenu"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="">
<i
className={`fa fa-bars ${iconColor} ${
location !== "/" ? "text-white" : ""
} `}
></i>
</span>
</button>
</div>
<div className="order-lg-0">
<Link to="/">
<img
width="50"
src={header && header.logo.url}
className="img-fluid"
alt=""
/>
</Link>
</div>
<div className="order-lg-2 d-lg-none">
<span
className="d-flex"
data-toggle="modal"
data-target="#mobileCartModal"
>
<span className="d-inline-block mr-1">
<i
className={`fa fa-shopping-cart ${iconColor} ${
location !== "/" ? "text-white" : ""
} `}
></i>
</span>
<span
className={`d-inline-block ${iconColor} ${
location !== "/" ? "text-white" : ""
} `}
>
{product.length}
</span>
</span>
</div>
<div
className="collapse navbar-collapse order-lg-1"
id="slideDownMenu"
>
<ul className="navbar-nav mr-auto px-3">
<li className="nav-item">
<Link className="nav-link" to="/products">
Shop
</Link>
</li>
<li className="nav-item dropdown">
<Link
className="nav-link dropdown-toggle"
to="#"
id="navbarDropdown"
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
Learn
</Link>
<div
className="dropdown-menu"
aria-labelledby="navbarDropdown"
>
<Link className="dropdown-item" to="#">
Process
</Link>
<Link className="dropdown-item" to="#">
About Us
</Link>
<Link className="dropdown-item" to="#">
Blog
</Link>
<Link className="dropdown-item" to="#">
News
</Link>
<Link className="dropdown-item" to="#">
Beyond The Bottle
</Link>
</div>
</li>
<li className="nav-item">
<Link
className="nav-link"
to="#"
data-toggle="modal"
data-target="#loginModal"
>
Login
</Link>
</li>
<li className="nav-item">
<Link
className="nav-link"
to="#"
data-toggle="modal"
data-target="#signupModal"
>
Sign Up
</Link>
</li>
</ul>
<form className="dvSearch my-2 my-lg-0 px-3">
<input
className={`form-control border-top-0 border-right-0 border-left-0 mr-sm-2 ${
window.innerWidth > 991 ? borderColor : ""
} ${location !== "/" ? "border-white" : ""} `}
type="text"
placeholder="Search"
aria-label="Search"
/>
<button className="btn my-2 my-sm-0" type="submit">
<i
className={`fa fa-search ${iconColor} ${
location !== "/" ? "text-white" : ""
} `}
></i>
</button>
</form>
</div>
</div>
</nav>
</div>
}
<div style={{ height: "10000px" }}></div>
</>
);
};
export default Header;
ACTIONS -
//ACTION CREATOR FETCH HOMEPAGE
export const fetchHomepage = () => {
const apiKey = process.env.REACT_APP_API_KEY;
const url = `https://api.json-generator.com/templates/UhZ_20Akrr7T/data?access_token=${apiKey}`;
return async (dispatch, getState) => {
const response = await fetch(url);
const data = await response.json();
dispatch({
type: actionTypes.SET_HOMEPAGE,
payload: data,
});
};
};
// remove homepage
export const removeHomepage = () => {
return {
type: actionTypes.REMOVE_HOMEPAGE,
};
};
//set nav bg color
export const setBgColor = (data) => {
return {
type: actionTypes.SET_NAV_BG_COLOR,
payload: data,
};
};
HOMEPAGE REDUCER-
import { actionTypes } from "../constants/action-types";
const homeiState = {
data: {},
bgColor: {},
isLoading: true,
};
export const homepageReducer = (state = homeiState, { type, payload }) => {
switch (type) {
case actionTypes.SET_HOMEPAGE:
return {
...state,
data: payload,
isLoading: false,
};
case actionTypes.REMOVE_HOMEPAGE:
return {
...state,
isLoading: true,
};
case actionTypes.SET_NAV_BG_COLOR:
return {
...state,
bgColor: payload,
};
default:
return state;
}
};
Solution 1:[1]
The useEffect's cleanup function is only called before the component unmounts, your Header component is not unmounting, thus it will not be called.
If you want to call removeHomepage, I suggest calling it in the event function when clicking on a header item or creating a new useEffect hook that reacts to changes to a certain redux value.
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 | Fawzi |