はじめに
独学でプログラミングを勉強しながら学んだことについて記録したと考えています。もし内容に誤りや改善点があれば、ご指摘いただけると幸いです。
アプリの概要
現在作っているものは、「達成したい目標(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の再取得するため無限ループの解決出来ました。
まとめ
依存関係によって無限ループされる問題はよく出てくる問題見たいですが、解決方法がわからなくて原因を見つけて、解決するまで時間がかかりました。まだまだ足りない部分が多いと思いました。