以下のように、componentDidMount()フック内でコンポーネントの状態を5秒ごとに変更しようとしています
import React, { Component } from 'react';
export default class ToTest extends Component {
constructor(props) {
super(props);
this.state = {
test: false
};
}
componentDidMount() {
setTimeout(() => { this.setState({ test: !this.state.test }) }, 5000);
}
renderDiv() {
if(this.state.test) {
return (<div>test is true</div>)
}
else {
return (<div>test is false</div>)
}
}
render() {
return (
<div>{ this.renderDiv() }</div>
);
}
}
ただし、実行は1回だけです。 falseからtrueに変わり、その後は何も変わりません。何が欠けていますか?
componentDidMount()
は、コンポーネントがマウントされたときに1回だけ実行され、スケジュールは1回だけです。定期的にスケジュールするには、setInterval()
を使用する必要があります。
また、現在の状態に基づいて状態を更新するときは、setState()
のコールバックを使用する必要があります。これは、reactがsetState()
への複数の呼び出しをバッチ処理する可能性があるため、以前の状態を取ります。
componentWillUnmount()
でタイマーをキャンセルすることを忘れないでください:
import React, { Component } from 'react';
export default class ToTest extends Component {
state = {
test: false,
};
componentDidMount() {
this.timer = setInterval(
() => this.setState(prevState => ({ test: !prevState.test })),
5000,
);
}
componentWillUnmount() {
clearInterval(this.timer);
}
// other methods ...
}
setTimeout
は一度だけ実行されます。探しているのはsetInterval
です。
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
WindowOrWorkerGlobalScope mixin(およびwindow.setTimeoutの後継)のsetTimeout()メソッドは、関数または指定されたコードを一度に実行するタイマーを設定しますタイマーが切れます。
と比べて
WindowOrWorkerGlobalScopeミックスインのsetInterval()メソッドrepeatedlyは、関数を呼び出すか、コードスニペットを実行します。各呼び出しの間に一定の時間遅延があります。
コメントで述べたように、setInterval
を使用する必要があります。関数setTimeout
は1回呼び出されます。コンポーネントがアンマウントするときは、必ずsetIntervalをクリアしてください。 https://reactjs.org/docs/react-component.html#componentwillunmount
コード。
import React, { Component } from 'react';
export default class ToTest extends Component {
constructor(props) {
super(props);
this.state = {
test: false
};
}
componentDidMount() {
this.timer = setInterval(() => { this.setState({ test: !this.state.test }) }, 5000);
}
componentWillUnmount() {
clearInterval(this.timer)
}
renderDiv() {
if(this.state.test) {
return (<div>test is true</div>)
}
else {
return (<div>test is false</div>)
}
}
render() {
return (
<div>{ this.renderDiv() }</div>
);
}
}