0
1

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.

stateの管理をReactからReduxに書き換える

Last updated at Posted at 2021-10-03

はじめに

前々からインターン先でReactを書いていましたがReduxに触ることはなかったです。

ただ自分でも勉強していた時期があったのですが、Reduxのflowと亜種の多さに負けて取り組めないでいました。

しかし9月から働き始めたインターン先でReduxを書かなければならなかったので、早急にキャッチアップをしました。最初はかなり躓きましたが、なんとか実装し切ることが出来ました。それでも、まだ整理しきれてなかったので今回まとめてみました。

Reduxの組み合わせは様々ですが、今回はデファクトスタンダードになりつつある?Redux toolkitを使用しました。

またReduxを使わずにuseStateで管理したものも作ったので、そちらと照らし合わせながら読んでもらえると理解が深まるかもです。

今回のデモアプリ

Qhf744SCqNpZzD3KOYPO1633272030-1633272176.gif

Reactのみのコード
code:https://codesandbox.io/s/jian-yi-huiruta-ver-react-lmkro?file=/src/hooks/useAllUsers.tsx:244-257
app:https://lmkro.csb.app/

Reduxを使用したコード
code:https://codesandbox.io/s/jian-yi-huiruta-ver-redux-nqk1k?file=/src/index.tsx
app:https://nqk1k.csb.app/

開発環境

ライブラリ バージョン
React 17.0.2
Redux toolkit 1.5.1
typescript 4.1.5
mui/material 5.0.1

異なる点

stateの設定方法

まずはstateの設定方法です。ReactであればuseStateを用いることで簡単に出来ます。

useStateを使用した場合

export type isUser = {
  1: boolean;
  2: boolean;
  3: boolean;
};


 const [modalUser, setModalUser] = useState<isUser>({
    1: true,
    2: true,
    3: true,
  });

  const [displayUser, setDisplayUser] = useState<isUser>({
    1: true,
    2: true,
    3: true,
  });

これをReduxで同じことを行うと以下のようになります。(今回はdispalyUserのみReduxで管理し、modalUserはReact同様コンポーネントで保持しています。)

Redux toolkitを使用した場合

SetUserSlice.tsx
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

export type isUser = {
  1: boolean;
  2: boolean;
  3: boolean;
};

export type isUserType = {
  displayUser: {
    1: boolean;
    2: boolean;
    3: boolean;
  };
};


const initialState: isUserType = {
  displayUser: {
    1: true,
    2: true,
    3: true,
  },
};

export const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {},
});

// action creatorsをエクスポート
export const { setDisplayUser } = userSlice.actions;

//reducerをエクスポート
export default userSlice.reducer;
store.tsx
export const store = configureStore({
  reducer: { user: userReducer },
});

これで同じようにdisplayUserの初期値を設定することが出来ました。

それでは試しにトップレベルのApp.tsxで呼び出してみましょう。

Redux toolkitでstateを参照するときはuseSelectorを使います。

App.tsx
const displayUser = useSelector((state: RootState) => state.user.displayUser)
console.log(displayUser)
// => {1: true, 2: true, 3: true}

これでuseStateで設定した時と同じようにstateを使うことが出来ます。

stateの更新方法

次にstateの更新方法です。

今回はモーダルの適用ボタンが押された時に走る処理に着目したいと思います。

useStateを使用した場合

App.tsx
  const onSubmitModal = (modalUser: isUser) => {
    setDisplayUser({
      ...modalUser,
    });
    isModalOpen(); // モーダルを閉じる関数
  };

setDispalyUserの中はスプレッド構文 と呼ばれる方法で同じ名前のプロパティに上書きを実行しています。ピンとこない人は下のことを同じことをやっているんだぁと思ってもらえたら大丈夫です。

setDisplayUser({
   1: modalUser[0]
   2: modalUser[1]
   3: modalUser[2]
});

次はこれと同じことをReduxでやってみます。ここは少しわかりづらくなるかもです。

setUserSlice.tsx
export const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {
    setDisplayUser: (state, { payload }: PayloadAction<isUser>) => {
      return { ...state, displayUser: payload };
    },
  },
});
App.tsx
const onSubmitModal = () => {
  dispatch(setDisplayUser({ ...modalUser }));
  isModalOpen();
};

ここで新しくreducersdispatchという単語が出てきましたが、
reducersは、useStateの第二引数に入るset~~~にあたる部分だとイメージしてもらうのがわかりやすいと思います。

dispatch に関しては reducersを使って更新する際に使うものです。

reducersdispatch などReduxは色んな単語が出てきます。最初からそれを全部覚えるのはシンドいので使いながら理解を深めていくのがおすすめです。

このように

  1. reducersにstateを更新する関数を書く
  2. その関数をdispatchを使って呼ぶ

という手順でstateを更新することができます。

まとめ

どうにかしてReduxを動かしたいという方の助けになればと思って書きました。最初からすべて理解するのは大変なので、色々なコードをたくさん見て、自分の手元で動かしながら学習していくのがいいと思います。

自分もまだまだ未熟なので今後精進していきたいと思います。

参考文献

この記事は以下の情報を参考にして執筆しました。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?