LoginSignup
0
0

More than 1 year has passed since last update.

Componentのローカルステート管理方法について

Posted at

Reactで状態管理をする方法についてまとめてみる

Reactの実務経験は無いので、誤りがあれば指摘いただければ幸いです!

状態管理の手法

  • useState
  • useReducer

useState

関数コンポーネントの中でローカルなstateを使うことができるフック
useStateは現在の state の値と、更新関数のペアを返します

Todos Component

const Todos = () => {
  const [title, setTitle] = useState("")

  const handleSubmit = (e) => {
    e.preventDefault();
    const data = {
      id: new Date().getTime(),
      title,
      created_at: new Date()
    };
    setTodos((prevData) => [...prevData, data]);
    setTitle("");
  };

  return (
    <>
      <h2>Todos</h2>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          onChange={(e) => setTitle(e.target.value)}
          value={title}
        />
      </form>
      <ul>
        {todos.map((todo) => (
          <TodoItem todo={todo} key={todo.id} />
        ))}
      </ul>
    </>
  );
};
export default Todos;

コンポーネント単位で管理しているため、親子関係になっていればpropsとしてstateを渡し、他のコンポーネントでデータを反映させることは可能。

親子関係がなく、それぞれが独立したコンポーネントの場合、後述する Redux useContext 等の props以外の情報共有手段が必要になる。

公式
https://ja.reactjs.org/docs/hooks-state.html

codesandbox
https://codesandbox.io/s/usestate-todo-app-2i51b?file=/src/components/TodoItem.jsx:105-113

useReducer

useStateでは、 現在のstateとstateを更新するための関数が返ってきていました。

useReducerは、第一引数に関数(reducer)、第二引数にstateの初期値を渡すと、現在のstatedispatchメソッドとペアで返ってきます。

dispatchは、reducerに actionを dispatchし、reducerに伝えます。
actionを受け取ったreducerは、action.typeで分岐して処理する内容をきめている。

ざっくり書くと、
一つ前の state と dispatch された actionを使って新しいstateを生成するための 「関数」 です。

公式サイトより↓

// state初期値
const initialState = {count: 0};

// action.type によって処理する内容を決める
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <>
      Count: {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}

onClick={() => dispatch({type: 'decrement'})} のように、 actionを  dispatchすると

reducer 関数の中で、 action.type の分岐が実行される。 

    case 'decrement':
      return {count: state.count - 1};

codesandboxで、簡単なフォームを作ってみました。
このサンプルでは、 use-immer を使用しています。

codesandbox
https://codesandbox.io/s/usereducer-form-mjnzj?file=/src/App.js

Flux In-Depth Overview
https://facebook.github.io/flux/docs/in-depth-overview#structure-and-data-flow

公式  useReducer
https://ja.reactjs.org/docs/hooks-reference.html#usereducer

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