Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
479
Help us understand the problem. What are the problem?

posted at

updated at

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

React hooksとは

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

useStateとは

useState()は、関数コンポーネントでstateを管理(stateの保持と更新)するためのReactフックであり、最も利用されるフックです。

stateとはコンポーネントが内部で保持する「状態」のことで、画面上に表示されるデータ等、アプリケーションが保持している状態を指しています。stateはpropsと違い後から変更することができます。

クラスコンポーネントと関数コンポーネントを比較してみる

クラスコンポーネントと関数コンポーネントにおける「状態」の扱い方の違いを確認してみます。

クラスコンポーネント

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

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

class Counter extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
    // クラスでは、コンストラクタ内で、this.stateの初期値{ count: initialState }をセット
      count: initialState,
      // 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: initialState })}>
            最初の数値に戻す
          </button>
        </div>
      </>
    )
  }
}

export default Counter

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

.isClose {
  display: none;
}

.isOpen {
  display: block;
}

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

関数コンポーネント

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

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

useStateの基本形

//const [状態変数, 状態を変更するための関数] = useState(状態の初期値);
const [count, setCount] = useState(initialState)

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

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

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

const Counter = () => {
  // countの初期値として、1~10までのランダムな数値を生成
  const initialState = Math.floor(Math.random() * 10) + 1
  // count という名前の state 変数を宣言、初期値 initialState をセット
  const [count, setCount] = useState(initialState)
  // 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(initialState)}>最初の数値に戻す</button>
      </div>
    </>
  )
}

export default Counter

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

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

最後に

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

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

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

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
479
Help us understand the problem. What are the problem?