LoginSignup
1
2

More than 3 years have passed since last update.

React入門#5 〜stateの設定と取得と変更〜

Last updated at Posted at 2020-11-07

はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ 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 Componentstateを持つことができません)
constructor()メソッドの中で宣言し、オブジェクト型で記述します。

src/Blog.jsx
class Blog extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            isPublished: false
        }
    }
    // 中略
}
export default Blog;

stateの取得

・ 同じコンポーネントの中なら、this.state.key名で取得することができます。
・ 子コンポーネントで参照したい場合は、propsとしてisPublishedの値を渡します。

src/Blog.jsx
render() {
    return (
        <Article
            title="Reactの基礎知識"
            isPublished={this.state.isPublished}
        />
    );
}

stateの変更

setstate()メソッドを使います。
・ 関数にラップするのが一般的です。

例えば、togglePublishedという関数を作り、その中でsetState()メソッドを使う感じです。
下の例では、setState()メソッドの中で、オブジェクト型を表す波括弧をつけて、isPublishedの真偽値を!で反転させています。

src/Blog.jsx
togglePublished = () => {
    this.setState({
        isPublished: !this.state.Published
    })
};

例えば、自身が運営するブログで、Reactの使い方というタイトルの記事を公開するかどうか切り替えるページがあったとします。

reactの使い方.png

Blog.jsx
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}の値になっているので、公開状態のチェックボックスをクリックしても変わリません。

Article.jsx
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;

そこで公開状態を反転させる関数を作りますが、この関数は子コンポーネントでは参照できないので、引き渡す形をとります。

Blog.jsx
  // 公開状態を反転させる関数
  togglePublished = () => {
    this.setState({
      isPublished: !this.state.isPublished,
    });
  };

toggleというpropsにして、関数型で渡します。(toggleとして渡した時に、this.togglePublishedを呼び出します。)
こうする事で、再レンダーが起きて、無限ループしてしまうのを防ぎます。

Blog.jsx
<Article title={"Reactの使い方"} isPublished={this.state.isPublished} toggle={() => this.togglePublished()} />

こちらも、無限ループを防ぐ為、クリック後に関数型としてprops.toggleを呼び出します。

Article.jsx
<input type="checkbox" checked={props.isPublished} id="check" onClick={() => props.toggle()} />

これでチェックボックスをクリックすると、チェックが切り替わる様になります。

react.gif

エラー例

関数型以外で記述してみます。

Article.jsx
<input type="checkbox" checked={props.isPublished} id="check" onClick={props.toggle()} />

無限ループしてしまいますよ!と怒られてしまいます。

無限ループするぞ!.png

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2