ReactJS自定义挂钩不保留它';美国
主要的场景是我想要一个定时器来获取新的通知,但有时我需要从我定义的间隔周期中获取通知,所以我把它放在一个useEffect包装器中,我在customHook中创建了一个状态,这样我就可以从其他组件中更改它,并在useEffect hook依赖项列表中使用该状态。现在我希望Compo1重新运行useEffect,但它不会发生 我有一个包含此package.json的项目:ReactJS自定义挂钩不保留它';美国,reactjs,react-hooks,Reactjs,React Hooks,主要的场景是我想要一个定时器来获取新的通知,但有时我需要从我定义的间隔周期中获取通知,所以我把它放在一个useEffect包装器中,我在customHook中创建了一个状态,这样我就可以从其他组件中更改它,并在useEffect hook依赖项列表中使用该状态。现在我希望Compo1重新运行useEffect,但它不会发生 我有一个包含此package.json的项目: { “名称”:“---”, “版本”:“1.2.0”, “私人”:没错, “依赖项”:{ “@babel/runtime”:“
{
“名称”:“---”,
“版本”:“1.2.0”,
“私人”:没错,
“依赖项”:{
“@babel/runtime”:“^7.7.7”,
“@date io/jalaali”:“^1.3.11”,
“@material ui/core”:“^4.11.2”,
“@material ui/图标”:“^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”,
“剪贴板复制”:“^3.1.0”,
“clsx”:“^1.1.1”,
“dotenv”:“^8.2.0”,
“环境指令”:“^10.0.1”,
“formik”:“^2.0.8”,
“i18next”:“^17.3.1”,
“jss”:“^10.0.0”,
“jss rtl”:“^0.2.3”,
“lodash”:“^4.17.15”,
“材料表”:“^1.54.1”,
“物料界面弹出状态”:“^1.6.1”,
“md5”:“^2.2.1”,
“时刻”:“^2.24.0”,
“jalaali时刻”:“^0.9.2”,
“notistack”:“^0.9.7”,
“num2”:“^3.1.3”,
“查询字符串”:“^6.9.0”,
“反应”:“^17.0.1”,
“反应循环进度条”:“^2.0.3”,
“反应检测脱机”:“^2.4.0”,
“react dom”:“^17.0.1”,
“反应文件图标”:“^1.0.0”,
“反应头盔”:“^6.1.0”,
“react-I18下一步”:“^10.13.2”,
“反应图像”:“^2.2.1”,
“反应最小饼图”:“^6.0.1”,
“反应时刻”:“^0.9.6”,
“react redux”:“^7.2.2”,
“react路由器”:“^5.2.0”,
“反应路由器dom”:“^5.2.0”,
“反应脚本”:“^4.0.1”,
“反应滑块向下”:“^2.4.5”,
“反应步骤向导”:“^5.3.0”,
“快速反应”:“^5.5.0”,
“redux”:“^4.0.5”,
“样式化组件”:“^4.4.1”,
“url解析”:“^1.4.7”,
“是”:“^0.28.0”
},
“脚本”:{
“开始”:“反应脚本开始”,
“构建”:“反应脚本构建”,
“测试”:“反应脚本测试”,
“弹出”:“反应脚本弹出”
},
“eslintConfig”:{
“扩展”:“反应应用程序”
},
“浏览者”:{
“生产”:[
">0.2%",
“没有死”,
“不是全部”
],
“发展”:[
“上一个chrome版本”,
“上一个firefox版本”,
“最后1个safari版本”
]
},
“依赖性”:{
“道具类型”:“^15.7.2”,
“类型脚本”:“4.1.3”
},
“决议”:{
}
}
我有两个组件和一个自定义钩子
我的定制挂钩:
export const useHeaderNotifUpdater=()=>{
const[signalUpate,dispatchUpdateNotifSignal]=useState(true);
控制台日志(signalUpate);
返回{signalUpate,dispatchUpdateNotifSignal};
};
成分1:
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));
从“react redux”导入{connect};
从“react router dom/withRouter”导入withRouter;
const Compo1=({history,balance,setBalance,setMobileVerifyStatus,userInfo})=>{
const{signalUpate}=useHeaderNotifUpdater();
const[notifs,setNotifs]=useState(新notifs({}));
const[notifsLoading,setNotifsLoading]=useState(true);
console.log('Compo1',signalUpate);
useffect(()=>{
设超时=0;
常数滴答=()=>{
clearTimeout(超时);
api.notifs.getAllNotifis()
。然后({data})=>{
设置通知(新通知(数据));
})
.catch(()=>{
})
.最后(()=>{
如果(notifsLoading)
setNotifsLoading(假);
超时=设置超时(勾选5000);
})
};
勾选();
return()=>{
clearTimeout(超时);
};
//eslint禁用下一行
},[signalUpate]);
返回{notifs?.length};
};
常量mapStateToProps=状态=>({
balance:state.auth.balance,
isMobileNotVerify:state.auth.isMobileNotVerify,
userInfo:state.auth.userInfo,
});
const mapDispatchToProps={
注销,
挫折平衡,
设置移动状态
};
导出默认连接(mapStateToProps、mapDispatchToProps)(带路由器(Compo1));
成分2:
const Compo2 = () => {
const {dispatchUpdateNotifSignal} = useHeaderNotifUpdater();
const handleUpdateNotifs=()=>{
dispatchUpdateNotifSignal(prevState => !prevState);
}
return <button onClick={handleUpdateNotifs}>Click me!</>;
};
export default Compo2;
const Compo2=()=>{
const{dispatchUpdateNotifSignal}=useHeaderNotifUpdater();
const handleUpdateNotifs=()=>{
dispatchUpdateNotifSignal(prevState=>!prevState);
}
返回点击我!;
};
导出默认组件2;
问题是状态在我的自定义挂钩内部,从外部更改,但在Compo1中从未更改!真奇怪
每次调用自定义钩子时,它都会创建一个新状态。您应该只在公共父组件上创建一个状态,或者使用上下文或管理状态库创建全局状态。这根本不是
useState
的工作方式。每个组件都有自己的状态。您正在使用两个不同的自定义挂钩实例。您可能必须使用Context
才能共享状态,因为您使用的是redux,为什么不将其放在redux中?这正是使用redux的要点:在用户之间共享公共状态components@luissmg我需要在其他组件中轻松地更改此项,是否可以使用redux?我没有写这个项目,所以我以前从未使用过redux。但是谢谢你的提示,使用redux非常简单。您可以通过在组件中使用useDispatch
的简单操作进行设置