0
1

More than 3 years have passed since last update.

[React]別々に useState で定義した相互依存する state は期待通り動かない

Posted at

React の useState をいろいろいじってるときに微妙にハマったのでメモ。

useState を複数使って state を定義しているときに、それらが相互依存しているとき期待通りに動かなかった。

なので、相互依存しているものは同じ state に入れることで解消しました。

サンプル

loadingtrue のとき、 submit できないようにしたいとする。
(loading === true のとき、 canSubmit === false にしたい)

import React, { FC, useState, useEffect } from 'react';

const StateDependOnEachOther: FC = () => {
  // 別々の state に定義したバージョン
  const [canSubmit, setCanSubmit] = useState(true);
  const [loading, setLoading] = useState(false);

  // loading の状態に合わせて canSubmit を変える
  const submitting = () => {
    setCanSubmit(() => {
      if (loading) {
        return false;
      }

      return true;
    });
  };

  // 同じ state に定義したバージョン
  const [state, setState] = useState({
    canSubmit2: true,
    loading2: false,
  });

  // loading の状態に合わせて canSubmit を変える
  const submitting2 = () => {
    setState(prevCanSubmit2 => {
      if (prevCanSubmit2.loading2) {
        return {
          ...prevCanSubmit2,
          canSubmit2: false,
        };
      }

      return {
        ...prevCanSubmit2,
        canSubmit2: true,
      };
    });
  };

  useEffect(() => {
    // loading を true に変更
    setLoading(true);
    setState(prevState => {
      return { ...prevState, loading2: true };
    });

    // loading === true のとき、 canSumit は false にしたい
    submitting();
    submitting2();
    // eslint-disable-next-line
  }, []);

  return (
    <>
      <div>別々の useState で定義: canSubmit: {`${canSubmit}`}</div>
      <div>同じ useState で定義 state.canSubmit2: {`${state.canSubmit2}`}</div>
    </>
  );
};

export default StateDependOnEachOther;

結果

  • 別々の useState で定義した場合は loading の変更が反映されず、 canSubmit は true のまま
  • 同じ useState 定義した場合は loading の変更が反映され、 canSubmit は false になる

実際に動かしたものがこちら

とりあえず useState に定義すればいいと思ってたけど、関連するものはまとめる、または1コンポーネントの中で useState は一つにして、必要なものは全部その中に突っ込む方が良さそう。

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