はじめに
タスク管理アプリを作成しています。
今回は 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では、新たなメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか?
興味のある方は、ぜひホームページをのぞいてみてくださ!
▼▼▼