我想添加setInterval以便能够从数据库中获取新数据而无需刷新页面,因此我使用useEffect,setInterval,useState来解决它,设置初始状态{refresh:false,refreshSells:null} 并且当刷新= true和refreshSells = setinterval()时有开关,但是我得到了烦人的警告 React Hook useEffect缺少依赖项:“ refreshSells”。包括它或删除依赖项数组 如果我添加refreshSells,它将是不可阻挡的循环
const Sells = () => {
const [allSells,setAllSells] = useState([])
const [refresh,setRefresh] = useState(false)
const [refreshSells , setRefreshSells] = useState(null)
const [hidden,setHidden] = useState(true)
useEffect(() => {
Axios.get('/sells')
.then(({data}) => {
setAllSells(data.sells)
})
.catch(() => {
alert('something went wrong,ask omar')
})
},[])
useEffect(() => {
if(refresh){
setRefreshSells(setInterval(() => {
Axios.get('/sells')
.then(({data}) => {
setAllSells(data.sells)
})
}, 60000));
}
else{
clearInterval(refreshSells)
}
return () => clearInterval(refreshSells)
},[refresh])
答案 0 :(得分:0)
setRefreshSells
更新内部状态,并且在当前渲染期间不更改refreshSells
。因此return () => clearInterval(refreshSells)
将尝试清除错误的时间间隔。
您应该使用useRef挂钩作为间隔:
const refreshSellsRef = useRef(null);
...
useEffect(() => {
if(refresh){
refreshSellsRef.current = setInterval(() => {
Axios.get('/sells')
.then(({data}) => {
setAllSells(data.sells)
})
}, 60000);
return () => clearInterval(refreshSellsRef.current);
}
},[refresh])
还要注意,return () => clearInterval(refreshSellsRef.current)
将在卸载时和refresh
更改时被调用。因此您不需要else {clearInterval(...)}
答案 1 :(得分:0)
如果您的业务逻辑允许将两种效果分开(每60秒自动刷新+单击某些按钮后手动刷新),则可以简化每种独立效果的代码:
useEffect(() => {
const interval = setInterval(() => {
Axios.get('/sells')
.then(({data}) => {
setAllSells(data.sells)
})
}, 60000)
return () => clearInterval(interval)
}, [])
useEffect(() => {
if (refresh) {
setRefresh(false)
Axios.get('/sells')
.then(({data}) => {
setAllSells(data.sells)
})
};
}, [refresh])
触发刷新后,您似乎忘记了setRefresh(false)
,但我不确定为什么首先需要refreshSells
...
答案 2 :(得分:0)
在第二个useEffect
中,您将更新状态refreshSells
,其中useEffect
期望useCallback
ref为依赖项。如果将refreshSells
作为对useEffect
的依赖项,则可能会遇到内存泄漏问题。
因此,我建议您尝试使用以下代码来解决您的问题。这样您还可以消除refreshSells
useEffect(() => {
let interval;
if (refresh) {
interval = setInterval(() => {
Axios.get('/sells')
.then(({ data }) => {
setAllSells(data.sells)
});
}, 4000);
}
return () => clearInterval(interval);
}, [refresh]);