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

個人学習メモ useEffectの無限ループ解決

Posted at

はじめに

 独学でプログラミングを勉強しながら学んだことについて記録したと考えています。もし内容に誤りや改善点があれば、ご指摘いただけると幸いです。:pray:

アプリの概要

 現在作っているものは、「達成したい目標(goal)、目標を達成するための計画(plan)、さらに計画を分解して小さしたタスク(task)に分解して効率的に目標を達成、管理できるアプリ」になります。

問題

 問題になった部分はタスクの完了値を(isCompleted)更新すると、無限ループのエラーになったのが問題でした。

const TaskList: React.FC = () => {
  const { tasks } = useAppSelector((state) => state.task);
  const { selectedPlan } = useAppSelector((state) => state.plan);
  const dispatch = useAppDispatch();
  const [editingTaskId, setEditingTaskId] = useState<string | null>(null);

  useEffect(() => {
    if (selectedPlan) {
      dispatch(taskList(selectedPlan._id));
    }
  }, [selectedPlan,tasks]);

  const handleStatusClick = (task: ITask) => {
    const nextStatus = !task.isCompleted;

    const updatedCompleted = { ...task, isCompleted: nextStatus };
    dispatch(
      updateTask({
        taskId: task._id,
        planId: task.plan_id,
        taskData: updatedCompleted,
      })
    )
  };

無限ループの流れ 

  • selectedPlanがある場合、計画(plan)を選択した場合dispatch(taskList(selectedPlan._id))が実行されtasksの状態が更新されます。
  • tasksがuseEffectの依存配列に含まれているため、tasksが更新されることでuseEffectが再実行されます。
  • 再びdispatch(taskList(selectedPlan._id))が実行され、tasksが更新される流れになっています。

解決策

const TaskList: React.FC = () => {
  const { tasks } = useAppSelector((state) => state.task);
  const { selectedPlan } = useAppSelector((state) => state.plan);
  const dispatch = useAppDispatch();
  const [editingTaskId, setEditingTaskId] = useState<string | null>(null);

  useEffect(() => {
    if (selectedPlan) {
      dispatch(taskList(selectedPlan._id));
    }
  }, [dispatch, selectedPlan]);

  const handleStatusClick = (task: ITask) => {
    const nextStatus = !task.isCompleted;

    const updatedCompleted = { ...task, isCompleted: nextStatus };
    dispatch(
      updateTask({
        taskId: task._id,
        planId: task.plan_id,
        taskData: updatedCompleted,
      })
    ).then(() => {
      if (selectedPlan) {
        dispatch(taskList(selectedPlan._id));
      }
    });
  };
  • useEffectの依存関係からtasksを削除しました。
  • handleStatusClickから完了値(isCompleted)を更新とdispatch(taskList(selectedPlan._id))を実行するように修正しました。
  • このように修正することで、tasksを依存配列に含めることなく、完了値(isCompleted)が更新されるとtaskListの再取得するため無限ループの解決出来ました。

まとめ

 依存関係によって無限ループされる問題はよく出てくる問題見たいですが、解決方法がわからなくて原因を見つけて、解決するまで時間がかかりました。まだまだ足りない部分が多いと思いました。:cry::cry:

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