gpt4 book ai didi

javascript - react 状态反复恢复到旧值

转载 作者:行者123 更新时间:2023-12-04 10:04:09 25 4
gpt4 key购买 nike

有一个组件“DateForm”在提交表单时改变“counterInfo”的全局状态。

//DateForm component submittal function. 
const submitDate = () =>{
props.setCounterInfo(dateInfo); //passes date info to be counterInfo state in App.js
props.setShowInputForm(false); //DateInfo component is no longer rendered
}

然后,在 app.js 中,counterInfo 状态被传递给 Timer 组件
const App = () => {
const [showInputForm, setShowInputForm] = useState(false);
const [counterInfo, setCounterInfo] = useState(undefined);
return (
<>
<Timer
counterInfo = {counterInfo}
></Timer>
{showInputForm &&
<DateForm
setShowInputForm = {setShowInputForm}
setCounterInfo = {setCounterInfo}
></DateForm>}
</>
);
}

Timer 函数内部有一个 useEffect Hook ,它每隔一秒使用 counterInfo 的值。
//Inside the Timer Component
const [currTime, setCurrTime] = useState(null);
useEffect (() => {
setInterval(() => {
let timeLeft = (new Date(`${Months(props.counterInfo.year)[props.counterInfo.month-1].name} ${props.counterInfo.day} ${props.counterInfo.year} ${props.counterInfo.hour}:${props.counterInfo.minute}:${props.counterInfo.second}`).getTime()) - new Date().getTime();
setCurrTime(timeLeft);
},1000);
return(clearInterval());
}, [props, setCurrTime]);

我打算发生的是当在 DateForm 中更新 counterInfo 的值时更新 Timer.js 中的 timeLeft 值,但是,当在 DateForm 中更改值时,counterInfo 的新值和旧值的结果当在 Timer.js 中使用 timeLeft 的值时,两者都会闪烁。这个问题不是由 Timer.js 中的任何代码引起的,因为我尝试将 useEffect Hook 移动到 app.js 并将值传递给 Timer,但问题仍然存在。唯一改变 setCounterInfo 状态的地方是 DateForm 组件。
有谁知道如何解决这个问题?

最佳答案

首先,interval 的语法有点错误。声明

  useEffect (() => {
let interval = setInterval(() => {...},1000);
return () => clearInterval(interval);
}, [props, setCurrTime]);

但不相关的是,React 默认在每次渲染后重新应用效果。这是有意的,有助于避免 React 组件中存在的一整类错误。
对于间隔,如果每次都应用渲染 setInterval被调用,它永远不会有机会实际运行
换句话说,此代码可能会产生一些副作用,如 useEffect在每次运行中只关心当时的现有值而忘记其他一切, interval不是这样的。
为此,从我的 Angular 来看,最佳实践是创建 useInterval自定义钩子(Hook),内部将同时存储回调
function useInterval(callback) {
const savedCallback = React.useRef();

useEffect(() => {
savedCallback.current = callback;
});


useEffect(() => {
function run() {
savedCallback.current();
}
let interval = setInterval(run ,1000);
return () => clearInterval(interval);
}, [])
}



//Inside the Timer Component
const [currTime, setCurrTime] = useState(null);

useInterval(()=>
setCurrTime((new Date(`${Months(props.counterInfo.year)[props.counterInfo.month-1].name} ${props.counterInfo.day} ${props.counterInfo.year} ${props.counterInfo.hour}:${props.counterInfo.minute}:${props.counterInfo.second}`).getTime()) - new Date().getTime()))

关于javascript - react 状态反复恢复到旧值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61671564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com