0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Reactを基本からまとめてみた【8】【React Hook (useState)②】

Last updated at Posted at 2021-09-01

はじめに

学習するに至った経緯

2020年より、未経験からエンジニアへの転職を目指し、某プログラミングスクールへ通う。入学後、『Ruby』を未経験から学ぶ人が多いのと『Ruby』の求人が思っていた以上に少ないので、卒業後、フロントエンドのエンジニアを目指す事に。
Reactの学習した事を言語化し、認識の深化による備忘録として記載。

useStateとは

関数コンポーネント内でstateを保持するためのフック。

フック(Hookとは)

React16.8で追加された新機能で、関数コンポーネントにstateやライフサイクルといったReactの機能を"接続する(hook into)"ための関数のこと。

useStateを使うと何ができるのか

useStateを用いることで、コンポーネントに状態(state)を持たせることができる。
状態(state)とは、コンポーネントに管理され、プライベートであるべき値のこと。

注意点

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

・ フックは条件分岐等では呼び出さない。
・ フックは呼び出される順番で状態を管理している。
・ 毎回同じ順番で呼び出さないとバグの原因となる。

クラスコンポーネントではフックは使えない

実際にコーディングしてみる

useStateの動作確認用のアプリを用意

create-react-appのtypescriptテンプレートを使用
terminal
npx create-react-app <ファイル名> --template typescript
or
yarn create react-app <ファイル名> --template typescript

countアプリで基本の動きを理解

① src / components / Counter.tsxを作成する
② App.tsxとCounter.tsxを作成する

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

function App() {
  return (
    <div className="App">
      <Counter />
    </div>
  );
}
export default App;
Counter.tsx
import React from 'react'
const Counter: React.VFC = () => {
    return <div>Counter</div>;
};
export default Counter;
(1):一般的な書き方
Counter.tsx
import React, {useState} from 'react'

const Counter: React.VFC = () => {
    const [count, setCount] = useState(100);
    return <button onClick={() => setCount(count + 1)}>{count}</button>;
};
export default Counter;
(2):新しいstateが前のstateに基づいて計算される場合
Counter.tsx
import React, { useState } from 'react';

const Counter: React.VFC = () => {
    const [count, setCount] = useState(100);
    return (
    <button 
      onClick={() => {
        setCount((prevCount) => prevCount + 1);
        setCount((prevCount) => prevCount + 1);
     }}
    >
    {count}
  </button>
  );
};
export default Counter;
(3):初期値の計算に時間がかかる場合
Counter.tsx
import React, { useState } from 'react';

function initializeCounter() {
    for (let i = 0; i < 20000; i++) {
        console.log(i);
    }
return 0;
}

const Counter: React.VFC = () => {
    const [count, setCount] = useState(() => {
        const initialValue = initializeCounter();
        return initialValue;
    });
    return (
    <button 
      onClick={() => {
        setCount((prevCount) => prevCount + 1);
        setCount((prevCount) => prevCount + 1);
     }}
    >
    {count}
  </button>
  );
};
export default Counter;

入力フォームをuseStateで管理する

src / components / InputForm.tsx
①:1つのステートフックで複数の入力フォームの状態を管理

InputForm.tsx
import React, { useState } from 'react';

const InputForm: React.VFC = () => {
    const [name, setName] = useState({first: '', last:''});
  return (
    <div>
      <input 
      value={name.first} 
      onChange={(e)=>
      setName((prevName)=>({
          first:e.target.value,
          last:prevName.last,
          }))
          }
          />
      <input
      value={name.last} 
      onChange={(e)=>
      setName((prevName)=>({
          ...prevName,
          last:e.target.value,
          }))
          }
      />
      <p>
      {name.first}
      {name.last}
      </p>
    </div>
  );
};

export default InputForm;

②:複数のステートフックで複数の入力フォームの状態を管理

InputForm.tsx
import React, { useState } from 'react';

const InputForm: React.VFC = () => {
    // const [name, setName] = useState({first: '', last:''});
    const [firstName, setFirstName] = useState('');
    const [lastName, setLastName] = useState('');
  return (
    <div>
      <input 
    //   value={name.first} 
    //   onChange={(e)=>
    //   setName((prevName)=>({
    //       first:e.target.value,
    //       last:prevName.last,
    //       }))
    //       }
    value={firstName}
    onChange={(e)=> setFirstName(e.target.value)}
          />
      <input
    //   value={name.last} 
    //   onChange={(e)=>
    //   setName((prevName)=>({
    //       ...prevName,
    //       last:e.target.value,
    //       }))
    //       }
    value={lastName}
    onChange={(e)=> setLastName(e.target.value)}
      />
      <p>
      {/* {name.first}
      {name.last} */}
      {firstName}
      {lastName}
      </p>
    </div>
  );
};

export default InputForm;

①と②のどちらを使うか

②を使う。
理由:コードがシンプルになる。変数名でどんな状態を管理しているかわかりやすい。

参考サイト

[【ReactHooks入門】第2回:useStateの理解]
(https://www.youtube.com/watch?v=sAtKilNWslo)
[【React Hooks】useStateの基本を理解しよう]
(https://tyotto-good.com/blog/usestate-basic)

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?