はじめに
タイトルについて記事にしました。
この記事で得る内容は以下の通りです。
・ stateの設定・取得・変更方法について
■ Reactに関する過去の記事はこちら
・ React入門#1 〜Reactの基礎知識〜
・ React入門#2 〜JSXについて〜
・ React入門#3 〜create-react-appの環境構築〜
・ React入門#4 〜コンポーネント間でデータの受け渡しと再利用をする〜
状態(state)とは
・ コンポーネントで管理する変数のことです。
・ Reactのコンポーネントだけで使うことができるstate
を、Local stateといいます。
・ propsとして、親のコンポーネントから子コンポーネントに渡すことができます。
なぜstateを使うのか
SPA開発時に、ページをリロードせず、JavaScriptでDOM操作をせずに表示を切り替えられるためです。
■ 注意点
・ render( )内で値を変更してはいけないというルールがあります。
・ 値を変更する時は、setstate( )というメソッドを使って値を変更します。
■ なぜrender( )内で値を変更してはいけないのか
state
の変更をすると、Virtual DOMを書き換える(再レンダー)処理が行われます。
再レンダーされたメソッドに値を変更する処理があると、state
変更→再レンダーの無限ループが起きてしまいます。ですので、setstate()
メソッドでstate
の変更を管理しています。
stateの設定方法
・ Class Componentが前提条件となります。(Functional Componentはstate
を持つことができません)
・ constructor()
メソッドの中で宣言し、オブジェクト型で記述します。
class Blog extends React.Component {
constructor(props) {
super(props);
this.state = {
isPublished: false
}
}
// 中略
}
export default Blog;
stateの取得
・ 同じコンポーネントの中なら、this.state.key名
で取得することができます。
・ 子コンポーネントで参照したい場合は、props
としてisPublishedの値を渡します。
render() {
return (
<Article
title="Reactの基礎知識"
isPublished={this.state.isPublished}
/>
);
}
stateの変更
・ setstate()
メソッドを使います。
・ 関数にラップするのが一般的です。
例えば、togglePublishedという関数を作り、その中でsetState()
メソッドを使う感じです。
下の例では、setState()
メソッドの中で、オブジェクト型を表す波括弧をつけて、isPublishedの真偽値を!で反転させています。
togglePublished = () => {
this.setState({
isPublished: !this.state.Published
})
};
例
例えば、自身が運営するブログで、Reactの使い方というタイトルの記事を公開するかどうか切り替えるページがあったとします。
import React from "react";
import Article from "./Article";
class Blog extends React.Component {
constructor(props) {
super(props);
// Articleの公開状態を変更する為のstateで、初期状態は'false'で非公開の状態にします
this.state = {
isPublished: false,
};
}
render() {
return (
<>
// isPublishedという変数名で子コンポーネントに引き渡す✳︎中身は上のconstructorを参照している状態
<Article title={"Reactの使い方"} isPublished={this.state.isPublished} />
</>
);
}
}
チェック状態がchecked={props.isPublished}
の値になっているので、公開状態のチェックボックスをクリックしても変わリません。
import React from "react";
const Article = (props) => {
return (
<div>
<h2>{props.title}</h2>
<label htmlFor="check">公開状態:</label>
<input type="checkbox" checked={props.isPublished} />
</div>
);
};
export default Article;
そこで公開状態を反転させる関数を作りますが、この関数は子コンポーネントでは参照できないので、引き渡す形をとります。
// 公開状態を反転させる関数
togglePublished = () => {
this.setState({
isPublished: !this.state.isPublished,
});
};
toggleというprops
にして、関数型で渡します。(toggleとして渡した時に、this.togglePublishedを呼び出します。)
こうする事で、再レンダーが起きて、無限ループしてしまうのを防ぎます。
<Article title={"Reactの使い方"} isPublished={this.state.isPublished} toggle={() => this.togglePublished()} />
こちらも、無限ループを防ぐ為、クリック後に関数型としてprops.toggle
を呼び出します。
<input type="checkbox" checked={props.isPublished} id="check" onClick={() => props.toggle()} />
これでチェックボックスをクリックすると、チェックが切り替わる様になります。
エラー例
関数型以外で記述してみます。
<input type="checkbox" checked={props.isPublished} id="check" onClick={props.toggle()} />
無限ループしてしまいますよ!と怒られてしまいます。