Help us understand the problem. What is going on with this article?

react hooks+redux toolkitを使ってtodoアプリを作ってみた

この記事はTOWN株式会社アドベントカレンダー6日目の記事です(大遅刻して申し訳ないです。。。)
https://adventar.org/calendars/4335

React HooksとはReact16.8から追加された機能で、関数コンポーネントにstateなどの機能を使えるようになった記法です。
https://ja.reactjs.org/docs/hooks-intro.html

Redux toolkitとはどうしても複雑な記述を書かなくてはいけないイメージが(個人的に)あるreduxを簡潔に書くことができるライブラリです。reduxの公式チームがリリースしているそうです。
https://github.com/reduxjs/redux-toolkit

今回はreact hooksとredux toolkitを使ってtodoアプリを作成してみました。

こちらが完成形です。
reduxsample.gif

アプリの作成

まずcreate-react-appを使ってアプリのテンプレートを作成します。

npx create-react-app hooks-toolkit-sample

パッケージをインストールします。

yarn add react-redux @reduxjs/toolkit

or

npm i react-redux @reduxjs/toolkit

yarn startもしくはnpm startでアプリを起動します。reactのロゴsvgなどのいらないファイルやいらない記述等は削除しておきます。

actionとreducerの作成

redux toolkitのcreateSliceを使用し、actionとreducerを同時に作成しています。このおかげでactionとreducerを別々のディレクトリに分ける必要がなくなりました。

modules/listModule.js
import { createSlice } from "@reduxjs/toolkit";

const listModule = createSlice({
    name: "list",
    initialState: [],
    reducers: {
      addList: (state, action) => [...state, action.payload],
      deleteList: (state, action) => state.filter(el => el.id !== action.payload),
    }
});

export default listModule;

storeの作成

reducerとmiddlewareを登録します。先ほどのmoduleのreducerをredux toolkitのcombineReducersを使って登録しています。

src/store.js
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import listModule from "./modules/listModule";

const rootReducer = combineReducers({
    list: listModule.reducer,
});

export const setupStore = () => {
    const store = configureStore({
        reducer: rootReducer,
    });
    return store
}

コンポーネントの作成

まずuseDispatch()を使ってactionが使えるようにします。

todoを追加するためのテキストのinputの操作ですが、inputのonChangehandleChangeList関数を設定して文字を入力するたびに関数が実行されるようにします。
そしてreact hooksのuseStateを用い、入力したテキストを一時的にnewListNameのstateに入れておきます。
addListボタンを押した瞬間にnewListNameを引数にしてactionのaddListを実行し、storeのstateにtodoのテキストが入ることで画面が更新されます。

components/App.js
import React from 'react';
import { useState } from 'react';
import { useDispatch, useSelector } from "react-redux";
import listModule from "../modules/listModule";
import List from "./List.js";

const App = () => {
  const lists = useSelector(state => state.list);

  const [newListName, setListName] = useState("");
  const dispatch = useDispatch();

  const addList = () => {
    if (newListName !== "") {
      dispatch(listModule.actions.addList({id: lists.length > 0 ? lists.reduce((a,b) => a.id > b.id ? a : b).id + 1 : 1, title: newListName}));
    }
    setListName("");
  };

  const handleChangeList = (e) => {
    setListName(e.target.value);
  };

  return (
    <div className="App">
      <p>Redux TODO sample</p>
      {lists.map((list) =>
        <List key={list.id} item={list} />
      )}
      <input type="text" onChange={handleChangeList} value={newListName}/>
      <button onClick={addList}>addList</button>
    </div>
  );
};

export default App;

components/List.js
import React from 'react';
import { useState } from 'react';
import { useDispatch, useSelector } from "react-redux";
import listModule from "../modules/listModule";

const List = (props) => {
  const { item } = props;
  const dispatch = useDispatch();

  const deleteList = () => dispatch(listModule.actions.deleteList(item.id));

  return (
    <div>
      {item.title}
      <button onClick={deleteList}>deleteList</button>
    </div>
  )
}

export default List;

ここまでクラスコンポーネントを使わず、かつとてもコンパクトにreduxのアプリを作成することが出来ました。書いていてかなり楽しかったので今度はもう少し複雑なアプリも作ってみようかと思います。

参考:
TypescriptとReact HooksでReduxはもうしんどくない
https://qiita.com/ky7ieee/items/b3f43ecc497b9115449a
Redux Hooks によるラクラク dispatch & states
https://qiita.com/Ouvill/items/569384e5c8c7ce78f98e
Redux の記述量多すぎなので、 Redux の公式ツールでとことん楽をする。 ( Redux Toolkit)
https://qiita.com/Ouvill/items/a76e9cbce569d01f2931

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
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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