私はまだReactでかなり新しいですが、私はゆっくりと研ぎ澄ましていて、私は私が行き詰まっている何かに遭遇しました。
私はReactで "timer"コンポーネントを構築しようとしています、そして正直に言うと、私がこれを正しく(または効率的に)行っているかどうかはわかりません。以下のコードでは、状態をオブジェクト{ currentCount: 10 }
を返すように設定し、componentDidMount
、componentWillUnmount
、およびrender
を使用していますが、状態を10から9までの「カウントダウン」にしかできません。
二部構成の質問:私は何が間違っているのですか?また、(componentDidMount
およびcomponentWillUnmount
を使用するのではなく)setTimeoutを使用するより効率的な方法はありますか?
前もって感謝します。
import React from 'react';
var Clock = React.createClass({
getInitialState: function() {
return { currentCount: 10 };
},
componentDidMount: function() {
this.countdown = setInterval(this.timer, 1000);
},
componentWillUnmount: function() {
clearInterval(this.countdown);
},
timer: function() {
this.setState({ currentCount: 10 });
},
render: function() {
var displayCount = this.state.currentCount--;
return (
<section>
{displayCount}
</section>
);
}
});
module.exports = Clock;
あなたのコードには4つの問題があります。
setState
メソッドを使用するのではありませんそれを修正してみましょう。
componentDidMount: function() {
var intervalId = setInterval(this.timer, 1000);
// store intervalId in the state so it can be accessed later:
this.setState({intervalId: intervalId});
},
componentWillUnmount: function() {
// use intervalId from the state to clear the interval
clearInterval(this.state.intervalId);
},
timer: function() {
// setState method is used to update the state
this.setState({ currentCount: this.state.currentCount -1 });
},
render: function() {
// You do not need to decrease the value here
return (
<section>
{this.state.currentCount}
</section>
);
}
これにより、タイマーが10から-Nに減少します。あなたが0に減少するタイマーが欲しいなら、あなたはわずかに修正されたバージョンを使うことができます:
timer: function() {
var newCount = this.state.currentCount - 1;
if(newCount >= 0) {
this.setState({ currentCount: newCount });
} else {
clearInterval(this.state.intervalId);
}
},
class Clock extends Component
を使用して10秒カウントダウンを更新しました
import React, { Component } from 'react';
class Clock extends Component {
constructor(props){
super(props);
this.state = {currentCount: 10}
}
timer() {
this.setState({
currentCount: this.state.currentCount - 1
})
if(this.state.currentCount < 1) {
clearInterval(this.intervalId);
}
}
componentDidMount() {
this.intervalId = setInterval(this.timer.bind(this), 1000);
}
componentWillUnmount(){
clearInterval(this.intervalId);
}
render() {
return(
<div>{this.state.currentCount}</div>
);
}
}
module.exports = Clock;
Hooksを使用して10秒のカウントダウンを更新しました(クラスを作成せずにstateやその他のReact機能を使用できるようにする新しい機能提案。現在はReact v16.7.0-alphaにあります)。
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
const Clock = () => {
const [currentCount, setCount] = useState(10);
const timer = () => setCount(currentCount - 1);
useEffect(
() => {
if (currentCount <= 0) {
return;
}
const id = setInterval(timer, 1000);
return () => clearInterval(id);
},
[currentCount]
);
return <div>{currentCount}</div>;
};
const App = () => <Clock />;
ReactDOM.render(<App />, document.getElementById('root'));
ありがとう@ dotnetom、@ greg-herbowicz
「this.state is undefined」が返される場合-タイマー機能をバインドします:
constructor(props){
super(props);
this.state = {currentCount: 10}
this.timer = this.timer.bind(this)
}