1
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 1 year has passed since last update.

【React】同じ画面にリダイレクトさせた後、更新後のstateを画面に表示したい

Last updated at Posted at 2023-03-22

はじめに

リダイレクト後に更新後のstateを表示させることについて、詰まったので簡単にまとめてみます

やりたいこと

データを削除した後に同じ画面にリダイレクトさせたい。その際、画面に表示されるデータは削除後の内容にしたい

前提

リダイレクトさせてもDOMの更新がされないため、画面には削除前のデータが表示されている状況でした

方法

はじめにuseEffectを使い、強制的にレンダリングさせる方法を考えましたが、これはパフォーマンスやデバッグの観点からreact的に非推奨のようでした。
次にuseRecoilでstateをグローバルに管理する方法も考えましたが、修正する影響範囲が多かったことから一旦はコンポーネント間でpropsの受け渡しをしてstateを更新させる方法を選択しました

ファイル(一部)

components/pages/MyData.tsx(親)


  const [datas, setDatas] = useState<Data[]>();
  const getDatas = async () => {
    const res = await axios.get(`${apiURL}/data`).then(function (res) {
      setDatas(res.data.datas);
    });
  }
  useEffect(() => {
    getDatas();
  }, []);

-  <DataCards pageSize={6} datas={datas} my={true} />
+  <DataCards pageSize={6} datas={datas} my={true} refreshData={getDatas} />

components/molecules/Cards.tsx(子)


type Props = {
  datas: Data[];
  my?: boolean;
+ refreshData?: () => void;
};

export const Datas = memo((props: Props) => {

+  const refreshDatas = () => {
+    if (props.refreshData !== undefined) {
+      props.refreshData()
+    }
+  }
  const navigate = useNavigate();

  return (
    <>
      {my ? (
-       <MyDataCard card={item} />
+       <MyDataCard card={item} datas={refreshDatas} />
      ) : (
        <DataCard card={item} />
    );
});

components/molecules/MyDataCard.tsx(孫)

type Props = {
  card: Card;
+ datas: () => void;
};

export const MyDataCard = memo((props: Props) => {
  const deleteData = (id: string) => {
    setIsOpen(false)
    axios
    .delete(`${apiURL}/data/${id}`)
    .then((res: AxiosResponse<Data>) => {
      if (res.status === 200) {
-        navigation("/");
        console.log("削除しました");
        toaster('削除しました', 'success');
+        props.datas()
      } else {
        console.log("失敗しました");
        toaster('失敗しました', 'warning');
      }
    })
    .catch(() => {
      toaster('システムエラーです', 'error');
      console.log("catch");
    });
  }

}

コンポーネントの関係

  • 親コンポーネント(MyData.tsx)
  • 子コンポーネント(DataCards.tsx)
  • 孫コンポーネント(MyDataCard.tsx)

処理の概要

①孫コンポーネントで削除ボタンをクリックするとデータを削除する関数を実行

  • 孫コンポーネントでonclickイベントにdeleteData関数を指定しています

②データを取得する関数を親から子を経由して受け取り、実行

  • 今回は子コンポーネントを経由する必要があるので、親と子、子と孫間でそれぞれpropsの受け渡しを定義しています
  • 最終的にdeleteData関数内で親コンポーネントで定義したgetDatas関数を実行しています

③親のstateが更新され、画面のレンダリングが走る

親コンポーネントで定義したgetDatas関数が孫コンポーネントで呼び出されると、関数内のsetDatasでstateが更新されます。
これによって孫コンポーネントでの変更が親コンポーネントに伝わり、レンダリングが走ります

おわりに

今後はuseRecoilも挑戦していきたいです。

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