BLOG

React/useStateについて

カウントアップアプリを作ってみる

まずcreate-react-appした状態から下記のように変更する。

・src/App.js

import React from 'react';
import './App.css';

function App() {
  return (
    <div className="App">

    </div>
  );
}

export default App;

src/logo.svgも削除

src/components/Counter.jsを作成

 ※rceスニペットで以下を記述

import React, { Component } from 'react'

export class Counter extends Component {
    render() {
        return (
            <div>
                
            </div>
        )
    }
}

export default Counter

これを修正

※class Counter下にrcoスニペットでconstructorを記述

import React, { Component } from 'react'

class Counter extends Component {
    constructor(props) {
        super(props)

        this.state = {
             count: 0
        }
    }

    render() {
        return (
            <div>

            </div>
        )
    }
}

export default Counter

カウントの変化が分かるようにカウントを表示する

カウントを変化させたいのでボタンをonClickメソッドで表示する

render(){}を更新

    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.incrementCount}>Count +</button>
            </div>
        )
    }

次にincrementCountメソッドを追加する

import React, { Component } from 'react'

class Counter extends Component {
    constructor(props) {
        super(props)

        this.state = {
             count: 0
        }
    }

//これを追加
    incrementCount = () => {
        this.setState({
            count:this.state.count + 1
        })
    }

    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.incrementCount}>Count +</button>
            </div>
        )
    }
}

export default Counter

counterコンポーネントをApp.jsに読み込む

Counter.js

import React from 'react';
import './App.css';
import Counter from './components/Counter.js';

function App() {
  return (
    <div className="App">
      <Counter />
    </div>
  );
}

export default App;

上記のカウンターコンポーネントをuseStateを使って作成する。

 まずカウンターフックコンポーネントを作成する。

src/component/CounterHook.jsを作成

※rfceスニペット

import React, {useState} from 'react'

function CounterHook() {
    return (
        <div>

        </div>
    )
}

export default CounterHook

useStateを使うにはクラスではなく関数コンポーネントが必要

関数コンポーネント内でlocalStateを使えるように、useStateをReactからインポートする

※Local stateとは

Global stateではない(Reduxの管理外であるような)stateをLocal stateと呼ぶ。

簡単にいうと、React.Componenrtを継承したクラスを使って管理される状態。

さっそく宣言していく。

まずuseStateフックを呼び出し、State宣言をする

useStateには引数を渡すことで初期値を設定する。また、stateの値と更新回数とペアにして返されるのでそれぞれに任意の名前を与える[count, setCount]

countがstate値となり、setCountがstateを更新する関数になる。

CounterHook.js

import React, {useState} from 'react'

function CounterHook() {

    const {count, setCount}  = useState(0)

    const incrementCount = () => {
        setCount(count + 1)
    }

    return (
        <div>

        </div>
    )
}

export default CounterHook

カウントと、ボタンを表示する

CounterHooks.js

import React, {useState} from 'react'

function CounterHook() {

    const [count, setCount]  = useState(0)

    const incrementCount = () => {
        setCount(count + 1)
    }

    return (
        <div>
            <h1>{count}</h1>
            <button onClick={incrementCount}>Count +</button>
        </div>
    )
}

export default CounterHook

関数コンポーネントにはthisは存在しないので、this.countやthis.incrementとはならない。

これをApp.jsにインポートする

App.js

import React from 'react';
import './App.css';
// import Counter from './components/Counter.js';
import CounterHook from './components/CounterHook';

function App() {
  return (
    <div className="App">
      {/* <Counter /> */}
      <CounterHook />
    </div>
  );
}

export default App;

フックを呼び出す上でのルール

・フックを呼び出すのはトップレベルのみ

フックをループや条件分岐、ネストされた関数内で呼び出してはいけない。

これを遵守することで、コンポーネントがレンダリングされる際に毎回同じ順番で呼び出されることが保証される。複数回useStateが呼び出された場合でもこれを守ることでフックの状態を正しく保持することが出来る。

・フックを呼び出すのはReactの関数内のみ

フックの呼び出しは必ず関数コンポーネント内で呼び出す、またはカスタムフック内から呼び出すようにする。これを守ることでコンポーネント内の全てのstateを正しく保持することができる。