はじめに
タスク管理アプリを作成しています。
今回は useState を親へ移動した際に起きたエラーです。
エラー内容について
useEffect must not return anything besides a function,
翻訳すると、
useEffect は関数以外のものを返してはなりません。
という意味です。
エラーが起きたきっかけ
useState を親コンポーネントに移動し、
子コンポーネント側で useEffect を使って初期化処理を書き換えました。
その際、もともと useState の初期値として使っていたロジックをそのまま useEffect に移したため、
関数ではなく 配列を return してしまったことが原因でエラーが出ました。
変更前(問題なく動いていたコード)
const [tasks, setTasks] = useState(() => {
const stored = localStorage.getItem("tasks");
const parse = JSON.parse(stored || "[]");
return parse.map(deserializeTask);
});
解決方法
return がエラーの原因だったので、
代わりに setTasks() を使ってステートを更新するように修正しました。
const { tasks, setTasks } = props;
useEffect(() => {
// localStorageにデータがあれば設定する
const stored = localStorage.getItem("tasks");
const parse = JSON.parse(stored || "[]");
- return parse.map(deserializeTask);
+ const deserialized = parse.map(deserializeTask);
+ setTasks(deserialized);
}, []);
useEffect ではなぜ return がダメなのか
useStateで使えていた理由:
- useState は 値を返すフック だから
- 初期値として配列や関数を返しても全く問題ない
一方で useEffect は :
-
returnに書いたものは React によって「クリーンアップ関数」として扱われる - そのため、関数以外(配列など)を return するとエラーになる
例:正しいクリーンアップ関数の使い方
useEffect(() => {
const timer = setInterval(() => {
console.log("定期実行中");
}, 1000);
return () => {
clearInterval(timer); // ← アンマウント時に実行されるクリーンアップ
};
}, []);
これで useEffect のエラーを回避しつつ、正しく状態を初期化できるようになりました!
JISOUのメンバー募集中!
プログラミングコーチングJISOUでは、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてくださ!
▼▼▼
