2
1

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.

useEffectのreturnには気をつけよう

Last updated at Posted at 2023-06-22

useEffectのreturn部分

前提:Reactで使われるuseEffectについて、第二引数に空配列[]を設定すると、useEffect内の処理はコンポーネントマウント時、returnにコールバックを設定するとコンポーネントアンマウント時にそれぞれ一度だけ実行される。

  useEffect(() => {
    // コンポーネントマウント時に実行
    return () => {
      // コンポーネントアンマウント時に実行
    };
  }, []);

アンマウント時に実行したいコールバック内で、例えばuseStateでセットした値を使おうとすると、うまくいかなかった。例えば、こんな感じ。

const [str, setStr] = useState<string>('initial string');
...

  useEffect(() => {
    setStr('updated string');
    return () => {
      console.log(str);  // initial string
    };
  }, []);

console.log(str); // updated string

useEffect外でのconsole.log()ではちゃんと'updated string'が出るのになぜだ...!?!?
setState()が非同期処理のためすぐにはセットされないことは知っていたのですが...

解決方法

const [str, setStr] = useState<string>('initial string');
...

  useEffect(() => {
    const outputString = 'updated string';
    setStr(outputString);
    return () => {
      console.log(outputString);  // updated string
    };
  }, []);

console.log(str); // updated string

returnのコールバックは、コールバックがセットされた時点での値を参照するようでした。
※ただの私の経験談なので実際は間違っている可能性があります
setState()は非同期であるためコールバックがセットされた時点ではまだstrに値が代入されていない可能性があります。
今回の実装ではsetState()するのはuseEffect()内だけだったので、

  • outputStringに値を保持しておく
  • setStr()する
  • return文内ではstrではなく保持して置いた値(outputString)を使う

これで動きました。

じゃあ後から代入した値を使いたいときはどうするんだろう...という疑問は残りますが...

残ってしまった疑問

例えばuseEffect外で...というか、コンポーネントマウント後にsetStateした値をreturnのコールバック内で使う場合ってどうするんだろう...

const [str, setStr] = useState<string>('initial string');

  useEffect(() => {
    return () => {
      console.log(outputString);  // initial string 👈これを"updated string"にしたいときって...
    };
  }, []);

// useEffect外で
  setStr("updated string");

わかったら追記します。

2
1
2

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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?