🦇

[React] useStateの使い方

2023/08/20に公開

はじめに

React HooksuseStateを学習しました。
開発メンバーにも共有するために本記事を執筆します。

本記事では、useStateを使って 3 つの下記の画像のような機能ページを作成します。
react-usestate-step01
+1ボタンをクリックすると、即座にCountが増えるページ
react-usestate-step03
入力欄に文字を入力すると、即座にNameAgeに反映するページ
react-usestate-step05
Add Taskをクリックすると、即座にタスクが増えるページ

前提条件

下記の作業が完了済みを想定しております。

ファイル構成

ファイル構成は下記のとおりです。

src
├── components
│   ├── useState01.tsx
│   ├── useState02.tsx
│   └── useState03.tsx
├── App.css
├── App.test.tsx
├── App.tsx
├── index.css
├── index.tsx
├── logo.svg
├── react-app-env.d.ts
├── reportWebVitals.ts
└── setupTests.ts

1. useState のキホン

まずはuseState のキホンを理解します。

キホン分法を理解できたと思うので、実際にコーディングします

  1. useStateを使ったコンポーネントを作成する
src/components/useState01.tsx
// useStateをインポートする
import React, {useState} from "react";

export const State = () => {
    // 初期値を0とする
    const [count, setCount] = useState(0)
    return (
        // <>: React Fragmentで外側を囲む必要あり
        <>
            // 現在のステータスを表示
            <p>Count: {count}</p>
            // クリックしたらsetCountを使い、前回の値を(preCount)に`+1`をする
            <button onClick={() => {setCount(preCount=>preCount+1)} }>+ 1</button>
            // クリックしたらsetCountを使い、初期値に戻す
            <button onClick={() => {setCount(0)} }>reset</button>
        </>
    )
}
  1. 自作コンポーネントをApp.tsxに追加し反映する
/src/App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
// 自作コンポーネントをインポート
import { Satate } from './components/useState01';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        // 自作コンポーネントの追加
      <State />
      </header>
    </div>
  );
}

export default App;

  1. package.jsonがあるディレクトリに移動し、下記コマンドを実行し React を起動する
npm start
  1. 起動が完了したらhttp://localhost:3000/にアクセスする

  2. +1ボタンでカウントが増えるか確認する
    react-usestate-step02
    +1ボタンを 3 回クリックすると、Countの数が 3 になります

以上でuseStateのキホンとなります

2. useState で Object を使う

次は、useStateを扱うデータをObjectの場合を解説します

  1. useStateを使い、扱うデータをObjectでコンポーネントを作成する
src/components/useState02.tsx
import React,  {useState} from "react";

export const SatateObject = () => {
    // name, ageのキーを持つオブジェクトを初期値にする
    const [profile, setProfile] = useState({name: '', age: ''})
    return (
        <>
            <form>
                // nameを入力する欄を作成する
                // 入力に変化がある場合(onChange)、setProfileを使い入力値(event.target.value)をprofileに設定する
                // ...profile: 変更するキー以外は現在値のままにする指定にする
                <input type='text' value={profile.name}
                    onChange={event => setProfile({...profile, name: event.target.value})}/>
                <input type='text' value={profile.age}
                    onChange={event => setProfile({...profile, age: event.target.value})}/>
            </form>
            // useStateを使ったprofileのnameを表示する
            <p>Name: {profile.name}</p>
            // useStateを使ったprofileのageを表示する
            <p>Age: {profile.age}</p>
        </>
    )
}
  1. 自作コンポーネントをApp.tsxに追加し反映する
/src/App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
// 自作コンポーネントをインポート
import { SatateObject } from './components/useState02';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        // 自作コンポーネントの追加
      <SatateObject />
      </header>
    </div>
  );
}

export default App;

  1. package.jsonがあるディレクトリに移動し、下記コマンドを実行し React を起動する
npm start
  1. 起動が完了したらhttp://localhost:3000/にアクセスする

  2. 左の入力欄(Name)に適当な文字を入力し、Name:の右隣に即座に文字が表示される事を確認する

  3. 右の入力欄(Age)に適当な文字を入力し、Age:の右隣に即座に文字が表示され、Name:の右隣にされている文字はそのままであること
    react-usestate-step03
    左の入力欄(Name)にふるたを入力し、右の入力欄(Age)に18と入力したページ

以上でuseStateで Object を使う解説になります。

3. useState で配列を使う

次は、useStateを扱うデータをListの場合を解説します

  1. useStateを使い、扱うデータをListでコンポーネントを作成する
src/components/useState03.tsx
import React, {useState} from "react";

export const SatateList = () => {
    // 空の配列を初期値にする
    const [taskList, setTaskList] = useState([])
    // ボタンをクリックされた配列に要素を1足す関数を作成する
    const addTask = () => {
        setTaskList([...taskList, {
            id: taskList.length
        }])
    }
    return (
        <>
            <button onClick={addTask}>Add Task</button>
            <ul>
                // mapを使い、<li>をの要素を作成する
                {taskList.map(task => (
                    <li key={task.id}>Task{task.id}</li>
                ))}
            </ul>
        </>
    )
}

  1. 自作コンポーネントをApp.tsxに追加し反映する
/src/App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
// 自作コンポーネントをインポート
import { SatateList } from './components/useState03';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        // 自作コンポーネントの追加
      <SatateList />
      </header>
    </div>
  );
}

export default App;

  1. package.jsonがあるディレクトリに移動し、下記コマンドを実行し React を起動する
npm start
  1. 起動が完了したらhttp://localhost:3000/にアクセスする

  2. 下記の画像のように表示される事を確認する
    react-usestate-step04

  3. Add Taskを 3 回クリックして 下記の画像のように表示される事を確認する
    react-usestate-step05

以上でuseStateで List を使う解説になります。

4. useState で型を指定する

src/components/useState01.tsx
// useStateをインポートする
import React,  {useState} from "react";

export const State = () => {
    // 初期値が0のため。数値型を指定する
    const [count, setCount] = useState<number>(0)
    return (
        <>
            <p>Count: {count}</p>
            <button onClick={() => {setCount(preCount=>preCount+1)} }>+ 1</button>
            <button onClick={() => {setCount(0)} }>reset</button>
        </>
    )
}

5. useState で自作の型を指定する

src/components/useState02.tsx
import React,  {useState} from "react";

// 自作で型を作成する
type TypeProfile = {
  name: string
  age: number
}

export const SatateObject = () => {
    // 作成した方をuseStateで使う型として利用する
    const [profile, setProfile] = useState<TypeProfile>({name: '', age: 0})
    return (
        <>
            <form>
                <input type='text' value={profile.name}
                    onChange={event => setProfile({...profile, name: event.target.value})}/>
                <input type='text' value={profile.age}
                    onChange={event => setProfile({...profile, age: event.target.value})}/>
            </form>
            <p>Name: {profile.name}</p>
            <p>Age: {profile.age}</p>
        </>
    )
}
GitHubで編集を提案

Discussion