The Major scenario is I want to have a timer for getting new notifications, but sometimes I need to get notifications out of interval cycle that I have defined, so I put it in a useEffect wrapper, And I made a state in a customHook so I can change it from other components and I use that sate in my useEffect hook dependency list. Now I expect Compo1 to re run useEffect but it's not happening...
I have a project with this package.json:
{
"name": "---",
"version": "1.2.0",
"private": true,
"dependencies": {
"@babel/runtime": "^7.7.7",
"@date-io/jalaali": "^1.3.11",
"@material-ui/core": "^4.11.2",
"@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.57",
"@material-ui/pickers": "^3.2.10",
"@material-ui/styles": "^4.11.2",
"animate.css": "^3.7.2",
"axios": "^0.21.1",
"clipboard-copy": "^3.1.0",
"clsx": "^1.1.1",
"dotenv": "^8.2.0",
"env-cmd": "^10.0.1",
"formik": "^2.0.8",
"i18next": "^17.3.1",
"jss": "^10.0.0",
"jss-rtl": "^0.2.3",
"lodash": "^4.17.15",
"material-table": "^1.54.1",
"material-ui-popup-state": "^1.6.1",
"md5": "^2.2.1",
"moment": "^2.24.0",
"moment-jalaali": "^0.9.2",
"notistack": "^0.9.7",
"num2persian": "^3.1.3",
"query-string": "^6.9.0",
"react": "^17.0.1",
"react-circular-progressbar": "^2.0.3",
"react-detect-offline": "^2.4.0",
"react-dom": "^17.0.1",
"react-file-icon": "^1.0.0",
"react-helmet": "^6.1.0",
"react-i18next": "^10.13.2",
"react-image": "^2.2.1",
"react-minimal-pie-chart": "^6.0.1",
"react-moment": "^0.9.6",
"react-redux": "^7.2.2",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.1",
"react-slidedown": "^2.4.5",
"react-step-wizard": "^5.3.0",
"react-toastify": "^5.5.0",
"redux": "^4.0.5",
"styled-components": "^4.4.1",
"url-parse": "^1.4.7",
"yup": "^0.28.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"prop-types": "^15.7.2",
"typescript": "4.1.3"
},
"resolutions": {
}
}
and I have two components and one custom hook with this contents
My custom hook:
export const useHeaderNotifUpdater = () => {
const [signalUpate, dispatchUpdateNotifSignal] = useState(true);
console.log(signalUpate);
return {signalUpate, dispatchUpdateNotifSignal};
};
Compo1:
import {connect} from "react-redux";
import withRouter from "react-router-dom/withRouter";
const Compo1 = ({history, balance, setBalance, setMobileVerifyStatus, userInfo}) => {
const {signalUpate} = useHeaderNotifUpdater();
const [notifs, setNotifs] = useState(new Notifs({}));
const [notifsLoading, setNotifsLoading] = useState(true);
console.log('Compo1',signalUpate);
useEffect(() => {
let timeout = 0;
const tick = () => {
clearTimeout(timeout);
api.notifs.getAllNotifis()
.then(({data}) => {
setNotifs(new Notifs(data));
})
.catch(() => {
})
.finally(() => {
if (notifsLoading)
setNotifsLoading(false);
timeout = setTimeout(tick, 5000);
})
};
tick();
return () => {
clearTimeout(timeout);
};
//eslint-disable-next-line
}, [signalUpate]);
return <div>{notifs?.length}</div>;
};
const mapStateToProps = state => ({
balance : state.auth.balance,
isMobileNotVerify: state.auth.isMobileNotVerify,
userInfo : state.auth.userInfo,
});
const mapDispatchToProps = {
logout,
setBalance,
setMobileVerifyStatus
};
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Compo1));
Compo2:
const Compo2 = () => {
const {dispatchUpdateNotifSignal} = useHeaderNotifUpdater();
const handleUpdateNotifs=()=>{
dispatchUpdateNotifSignal(prevState => !prevState);
}
return <button onClick={handleUpdateNotifs}>Click me!</>;
};
export default Compo2;
The problem is the state is inside of my custom hook, is change from the outside, but never changes in Compo1 ! which is weird!