Help us understand the problem. What is going on with this article?

React hooksを基礎から理解する (useState編)

React hooksとは

React 16.8 で追加された新機能です。
クラスを書かなくても、 stateなどのReactの機能を、関数コンポーネントでシンプルに扱えるようになりました。

クラスコンポーネントと関数コンポーネント

クラスコンポーネントと関数コンポーネントの違いを確認してみます。

クラスコンポーネント

import React from 'react'
import './styles.css'

// countの初期値として、1~10までのランダムな数値を生成 
const intialState = Math.floor(Math.random() * 10) + 1

class Counter extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    // クラスでは、コンストラクタ内で、this.stateの初期値{ count: intialState }をセット
      count: intialState,
      // this.stateの初期値{ open: false }をセット
      open: true
    }
  }
  // toggleメソッドを作成 
  toggle = () => {
    this.setState({ open: !this.state.open })
  }

  render() {
    return (
      <>
        <button onClick={this.toggle}>
          {this.state.open ? 'close' : 'open'}
        </button>
        <div className={this.state.open ? 'isOpen' : 'isClose'}>
          <p>現在の数字は {this.state.count} です</p>
          {/*ボタンをクリックした時に、this.setState()を呼ぶことでcountステートを更新 */}
          <button
            onClick={() => this.setState({ count: this.state.count + 1 })}
          >
            + 1
          </button>
          <button
            onClick={() => this.setState({ count: this.state.count - 1 })}
          >
            - 1
          </button>
          <button onClick={() => this.setState({ count: 0 })}>0</button>
          <button onClick={() => this.setState({ count: intialState })}>
            最初の数値に戻す
          </button>
        </div>
      </>
    )
  }
}

export default Counter

ちなみにstyles.cssの中身はこれだけ。

.isClose {
  display: none;
}

.isOpen {
  display: block;
}

こんなカウンターが出来ました。

関数コンポーネント

hooks の useState を使ってクラスコンポーネントから関数コンポーネントに書き換えてみます。
関数コンポーネントの基本形は以下の通り。

const ExComponent = props => {
  // ここでhooksを使える
  return <div />
}

useStateの基本形

useState によって React の state の機能を関数コンポーネントに追加します。

const [count, setCount] = useState(intialState)

// ちなみにクラスコンポーネントでは、、、
this.state = {
  count: intialState
}

useState の左辺の state 変数には任意の名前を付けることが出来ます。
(分割代入構文をイメージすると理解しやすいです。)

  • 1つ目の要素: state の現在の値
  • 2つ目の要素: state の現在の値を更新するための関数
  • state が更新されても intialStateintialState として保持される
// 関数コンポーネント内で state を使えるようにするため、useState をインポート 
import React, { useState } from 'react'
import './styles.css'

const Counter = () => {
  // countの初期値として、1~10までのランダムな数値を生成
  const intialState = Math.floor(Math.random() * 10) + 1
  // count という名前の state 変数を宣言、初期値 intialState をセット
  const [count, setCount] = useState(intialState)
  // open という名前の state 変数を宣言、初期値 true をセット
  const [open, setOpen] = useState(true)
  // toggleの関数を宣言
  const toggle = () => setOpen(!open)

  return (
    <>
      <button onClick={toggle}>{open ? 'close' : 'open'}</button>
      <div className={open ? 'isOpen' : 'isClose'}>
        <p>現在の数字は{count}です</p>
        {/* setCount()は、countを更新するための関数。countを引数で受け取ることも出来る */}
        <button onClick={() => setCount(prevState => prevState + 1)}>
          + 1
        </button>
        <button onClick={() => setCount(count - 1)}>- 1</button>
        <button onClick={() => setCount(0)}></button>
        <button onClick={() => setCount(intialState)}>最初の数値に戻す</button>
      </div>
    </>
  )
}

export default Counter

クラスで書いた場合と、同じ結果になりました:heart_eyes:

再レンダリング後も React はその変数の現在の state の値をそのまま持っており 、最新の state の値を関数に渡します。現在の state の値を更新したい場合は、setState を呼びます。

最後に

次回は useEffect について書きたいと思います。

useState関連のQiita記事書きました :point_down_tone2:
React公式チュートリアルのクラスコンポーネントを関数コンポーネントに書き替える

参考にさせていただいたサイト

https://reactjs.org/

seira
エイチームライフスタイルのフロントエンドデザイナ。 最近はReact, Rails, php, jQuery Sass, Photoshop, Figmaなどを触っています。
life-a-tm
人生のイベントや日常生活に密着した比較サイト、情報サイト等様々なウェブサービスを企画・開発・運営
https://life.a-tm.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away