首先,我知道有关此主题的很多问题,并且我已经阅读了我认为适用于我的情况的所有问题。特别是这个线程React component initialize state from props似乎是我所需要的,但是这里没有提到任何工作。无论如何,到我的代码。这只是一个简单的倒数计时器,以用户输入(以分钟为单位)作为起点:
class Timer extends Component {
constructor(props) {
super(props);
this.state = {
minutes: props.workPeriod,
seconds: 0
};
}
componentDidMount() {
setInterval(() => {
const {minutes, seconds} = this.state
console.log("minute state: ", minutes)
if(this.props.countdownHasStarted) {
if(seconds > 0) {
this.setState(({seconds}) => ({
seconds: seconds - 1
}))
}
if(seconds === 0) {
if(minutes === 0) {
clearInterval(this.myInterval)
} else {
this.setState(({minutes}) => ({
minutes: minutes - 1,
seconds: 59
}))
}
}
}
}, 1000)
}
...
const selector = formValueSelector('intervalSettings')
Timer = connect(state => {
const workPeriod = selector(state, 'workPeriod')
return {
workPeriod,
countdownHasStarted: state.countdownHasStarted
}
})(Timer)
由于所有组件都位于组件树上,因此我使用了Redux,因此workPeriod来自Redux存储,如果有什么不同的话。 当我在控制台中打印“分钟”时,我不确定,并且在渲染时确定,我只是得到分钟的NaN。如何使props.workPeriod进入状态,以便对其进行定义并能够对其进行操作?
我介绍了如何从Redux商店获得workPeriod,以防万一我的麻烦与事有关,但是{this.props.workPeriod}效果很好,所以我认为那里一切都很好。
谢谢!
(已编辑,以纳入先前的建议和问题)
答案 0 :(得分:3)
之所以发生这种情况,是因为redux存储是用空对象初始化的。到redux形式的reducer初始化其自己的initialValues
时,<Timer />
组件将获得未定义的值workPeriod
并启动setInterval()。这是我使用React Hooks解决此问题的方法:
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { formValueSelector } from "redux-form";
let Timer = ({ workPeriod, countdownHasStarted }) => {
const [seconds, setSeconds] = useState(0);
const [minutes, setMinutes] = useState();
useEffect(() => {
// first initialize the minutes when the workPeriod is initialized
setMinutes(workPeriod);
}, [workPeriod]);
useEffect(() => {
let interval;
if (minutes) {
interval = setInterval(() => {
console.log("minute state: ", minutes);
if (countdownHasStarted) {
if (seconds > 0) {
setSeconds((sec) => sec - 1);
}
if (seconds === 0) {
if (minutes === 0) {
clearInterval(interval);
} else {
setMinutes((min) => min - 1);
setSeconds(59);
}
}
}
}, 1000);
}
return () => {
// cleanup function
clearInterval(interval);
};
}, [countdownHasStarted, minutes, seconds]);
return (
<div className="numbers">
<div className="box" id="minutes">
<p>{minutes}</p>
</div>
<div className="box" id="colon">
<p>:</p>
</div>
<div className="box" id="seconds">
<p>{seconds < 10 ? `0${seconds}` : seconds}</p>
</div>
</div>
);
};
Timer = connect((state) => {
const selector = formValueSelector("intervalSettings");
const workPeriod = selector(state, "workPeriod");
return {
workPeriod,
countdownHasStarted: state.countdownHasStarted,
};
})(Timer);
export default Timer;
答案 1 :(得分:1)
const {minutes, seconds} = this.setState
你的意思是
const {minutes, seconds} = this.state
?