我这里有一个简单的计时器应用程序,有一天可能会变成番茄工作法应用程序。我现在正在学习生命周期方法。
问题来了。我想在计时器达到 0 时从屏幕上删除计时器。最终,它会立即被不同的计时器取代,但我还没有达到那个部分。我很确定问题出在这里:
componentDidUpdate = () => {
if (this.state.count-1 === -2) {
this.props.timerOverCallback()
}
}
最初,我尝试了这个if语句:!(this.state.count-1)。计数器一直以 2 而不是 0 清除。
然后我尝试了这个.state.count-1 === -1,因为这似乎仍然有意义。计数器一直以 1 而不是 0 清除。
到那时,一种模式已经出现,我尝试了这个.state.count-1 === -2。我的问题是:为什么我需要与 -2 而不是 -1 进行比较?与 -2 进行比较似乎不是特别可靠,真的。那么清除计时器的最佳方法是什么?
以下是完整代码:
class Timer extends Component {
static propTypes = {
timerOverCallback: PropTypes.func.isRequired,
count: PropTypes.number.isRequired,
}
constructor(props) {
super(props)
this.state = {
timerOverCallback: this.props.timerOverCallback,
count: this.props.count,
}
}
decrease = () => {
this.setState(
prevState => ({count: prevState.count - 1})
)
}
componentDidMount = () => {
this.interval = setInterval(this.decrease, 1000)
}
componentDidUpdate = () => {
if (this.state.count-1 === -2) {
this.props.timerOverCallback()
}
}
componentWillUnmount = () => { clearInterval(this.interval) }
render() {
return (
<Text style={styles.count}>{this.state.count}</Text>
)
}
}
export default class App extends Component {
constructor() {
super()
this.state = {
timerOn: false,
}
}
toggleTimer = () => {
this.setState(
prevState => ({timerOn: !prevState.timerOn})
)
}
render() {
return (
<View
style={styles.fillAndCenter}>
{this.state.timerOn ?
<Timer
count={5}
timerOverCallback={this.toggleTimer}
/> : <View/>
}
<Button
title='Toggle Timer'
onPress={this.toggleTimer}
/>
<Text>
{this.state.timerOn ? 'On' : 'Off'}
</Text>
</View>
)
}
}
更新 05/08/2018:
我接受了加巴克的建议,并放置了...
if (this.state.count < 0) this.state.timerOverCallback()
。在此.减少并摆脱了组件DidMount。但是,我意识到当 this.state.count = -1 时,该组件实际上已达到其生命周期的渲染阶段,这似乎有问题。确实,屏幕从未真正更新为 -1,但渲染函数肯定会被调用,所以屏幕没有更新的事实似乎是巧合(对吧!?
然后我意识到,即使我过于挑剔,也有简单的方法可以解决这个问题:
shouldComponentUpdate = (nextProps, nextState) => {
return nextState.count > -1
}
这是从React-Native站点componentDidUpdate
的:
componentDidUpdate() is invoked immediately after updating occur
因此,假设您的屏幕显示0
(this.state.count = 0)
。this.decrease
得到调用 =>this.state.count = -1
=> 组件得到更新 =>componentDidUpdate
被调用(在渲染之前,所以屏幕仍然显示0
)
this.state.count - 1 = -2
,调用timeOverCallback()
并停止屏幕呈现当前this.state.count
,这是-1
您可以更改为this.state.count === -1
或者我认为更好的方法是停止使用componentDidUpdate
,将检查放入this.decrease
:当您看到this.state.count < 0
呼叫时timeOverCallback()