引き続きReact
[Get started]から始めるReact開発:その1
[Get started]から始めるReact開発:その2:Rendering Elements
[Get started]から始めるReact開発:その3:Components and Props
[Get started]から始めるReact開発:その4(State and Lifecycle①
[Get started]から始めるReact開発:その4(State and Lifecycle②
今回から直訳風ではなくできるだけ意訳して書きます。
この前までの読んでてちょっと意味不明だなと思ったので。
つーか今回めっちゃ長い。
State and Lifecycle
一つ前のセクションからの時計について考えてみます。
これまでのところ私たちはUIを更新する一つの方法を学んだだけです。
レンダリングされたアウトプットを変更するためにはReactDOM.render()を呼びます。
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(
element,
document.getElementById('root')
);
}
setInterval(tick, 1000);
このセクションの中では、本当に再利用が可能でカプセル化された時計コンポーネントの作り方について学びます。
この時計コンポーネントは自身で時間をセットして毎秒自分自身で更新します。
まず私たちは、時計の外観をカプセル化することができます。
function Clock(props) {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {props.date.toLocaleTimeString()}.</h2>
</div>
);
}
function tick() {
ReactDOM.render(
<Clock date={new Date()} />,
document.getElementById('root')
);
}
setInterval(tick, 1000);
しかし上記は重要な要件が抜けてしまっています。
時計に時間をセットし、毎秒UIを更新することはClockの中で実装すべきです。
理想的としては、データを渡さずに一度で書きたい(<clocke />)ですし、自身で更新を行う`Clock'を持てたらいいなと考えます。
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
これを実現するにはClockコンポーネントにStateを加える必要があります。
Stateはpropsに似ていますが、コンポーネント内部で完結しておりコンポーネントによって完全にコントロールされています。
以前述べたように、クラスとして定義されたコンポーネントはいくつかの追加機能があります。
Local Stateがまさにそのクラスだけが利用できる機能です。
Converting a Function to a Class
Clockのようなfunctional componentを5つのステップでclassにすることができます。
-
React.Componentの拡張(extends)として同じ名前のES6クラスを作成する -
render()という空っぽのメソッドを追加する -
render()メソッドの中に機能の中身を移す -
render()の中でpopsをthis.propsに変える - 残りの空の関数宣言を削除する
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
上記によりClockは関数というよりはクラスとして新しく定義されました。
これによりlocal stateやlifecycle hooksと言った追加機能が利用できるようになります。
Adding Local State to a Class(クラスのlocal stateを加える)
3ステップでdateをpropsからstateに動かしましょう。
-
render()メソッド内でthis.props.dateをthis.state.dateに変えます
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
- 初期の
this.stateを割り当てるclass constructorを加えます
ベースのコンストラクタにpropsを渡す方法に注意してください。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
クラスコンポーネントは常にpropsでベースのコンストラクタを呼ばなければなりません。
-
<Clock />要素からdate propを外します
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
後でコンポーネント自体の動きの変更に戻ってタイマーコードを加えます。
結果としては下記のようになります。
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,
document.getElementById('root')
);
次はClockの自身をタイマー設定と毎秒更新処理を作成します。
長かったので分割します。