У меня есть простое приложение для таймера, которое однажды может превратиться в приложение Pomodoro. Я изучаю методы жизненного цикла прямо сейчас.
Вот проблема. Я хотел бы убрать таймер с экрана, как только он достигнет 0. В конце концов, он будет немедленно заменен другим таймером, но я еще не достиг этой части. Я почти уверен, что проблема здесь:
componentDidUpdate = () => {
if (this.state.count-1 === -2) {
this.props.timerOverCallback()
}
}
Первоначально я пробовал это утверждение if: ! (This.state.count-1) . Счетчик продолжал очищаться в 2 вместо 0.
Затем я попытался this.state.count-1 === -1 , потому что это, казалось, имело смысл. Счетчик продолжал очищаться на 1 вместо 0.
К тому времени появился шаблон, и я попытался this.state.count-1 === -2 . У меня вопрос: зачем мне сравнивать с -2 вместо -1? Сравнение с -2 не кажется особенно надежным, правда. Так как же лучше всего очистить таймер на 0?
Вот полный код:
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()
... в этом. Уменьшаем и избавляемся от componentDidMount. Однако я понял, что компонент фактически достиг стадии визуализации своего жизненного цикла, когда this.state.count = -1, что кажется проблематичным. Это правда, что экран никогда не обновлялся до -1, но функция рендеринга определенно вызывалась, поэтому тот факт, что экран не обновлялся, казался случайным (верно!?).
И тогда я понял, что, даже если я был слишком разборчив, есть и простой способ исправить это:
shouldComponentUpdate = (nextProps, nextState) => {
return nextState.count > -1
}