[英]Warning: Cannot update during an existing state transition (such as within `render`)
[英]React Warning: Cannot update during an existing state transition (such as within `render`)
我有渲染Timer
组件的ResetPassword
组件,下面是它们的代码 -
重发密码.js
class ResetPassword extends Component{
constructor(props){
super(props);
this.state = {
resendActive: false
};
}
endHandler(){
this.setState({
resendActive: true
})
}
render(){
return (
<Timer sec={5} counter={this.state.counter} end={this.endHandler.bind(this)}/>
)
}
}
计时器.js
const Timer = (props) => {
const [sec, setSec] = useState(props.sec);
useEffect(() => {
setSec(props.sec);
const intr = setInterval(() => {
setSec((s) => {
if(s > 0)
return --s;
props.end(); // Line: causing warning
clearInterval(intr);
return s;
});
}, 1000)
return () => {
clearInterval(intr);
}
}, [props.counter])
return (
<span>{sec > 60 ? `${Math.floor(sec/60)}:${sec - Math.floor(sec/60)}`: `${sec}`} sec</span>
)
}
In Above code I'm using timer in ResetPassword and I want a function call when timer ends so I'm passing endHandler as end in Timer component but calling that function giving - Warning: Cannot update during an existing state transition (such as within 'render')
,谁能让我知道我在这里做错了什么?
提前致谢
setSec
是 state 更新 function 并且您使用功能 state 更新变体。 此更新 function 回调必须是纯 function,即副作用为零。 props.end()
的调用是一个副作用。
将props.end
的副作用调用拆分为自己的效果挂钩,使其独立于 state 更新程序 function。
const Timer = (props) => {
const [sec, setSec] = useState(props.sec);
useEffect(() => {
setSec(props.sec);
const intr = setInterval(() => {
setSec((s) => {
if (s > 0) return --s;
clearInterval(intr);
return s;
});
}, 1000);
return () => {
clearInterval(intr);
};
}, [props.counter]);
useEffect(() => {
console.log(sec);
if (sec <= 0) props.end(); // <-- move invoking `end` to own effect
}, [sec]);
return (
<span>
{sec > 60
? `${Math.floor(sec / 60)}:${sec - Math.floor(sec / 60)}`
: `${sec}`}{" "}
sec
</span>
);
};
创建一个useInterval
挂钩
const useInterval = (callback, delay) => {
const savedCallback = useRef(null);
useEffect(() => {
savedCallback.current = callback;
});
useEffect(() => {
const id = setInterval(savedCallback.current, delay);
return () => clearInterval(id);
}, [delay]);
};
更新Timer
以使用间隔挂钩
const Timer = ({ end, sec: secProp}) => {
const [sec, setSec] = useState(secProp);
// Only decrement sec if sec !== 0
useInterval(() => setSec((s) => s - (s ? 1 : 0)), 1000);
useEffect(() => {
!sec && end(); // sec === 0, end!
}, [sec, end]);
return (
<span>
{sec > 60
? `${Math.floor(sec / 60)}:${sec - Math.floor(sec / 60)}`
: `${sec}`}{" "}
sec
</span>
);
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.