🦔

[React] <react-useから学ぶ> useMountedState編

2022/03/15に公開

github react-use useMountedState

import { useCallback, useEffect, useRef } from 'react';

export default function useMountedState(): () => boolean {
  const mountedRef = useRef<boolean>(false);
  const get = useCallback(() => mountedRef.current, []);

  useEffect(() => {
    mountedRef.current = true;

    return () => {
      mountedRef.current = false;
    };
  }, []);

  return get;
}

使用例

codesandboxでの処理の流れ

下記の操作を行い、consoleに注目してほしい。

  1. App setBoobuttonを押す
    CountUpButton mountedState false
    useMountedState useEffect
    useEffectのタイミングでmountedState()にtrueが入るが、refなのでCountUpButtonはrenderされないので、画面上はfalseになっている
  2. CountUpButton setNumbuttonを押す
    CountUpButton button mountedState true
  3. App setBoobuttonを押す

Appで管理されているbooがtrueになると、CountUpButtonがmountされる。
consoleに注目してほしいが、CountUpButtonがmount時は、CountUpButton mountedState falseと表示されている。
しかしconsoleでのuseMountedState useEffect時に、mountedState()にtrueが入るが、useMountedState内でrefで管理しているため、useEffectでtrueに変更しても再度renderされない。
よってuseMountedState useEffect後にmountedState()にはtrueが実際は入っている。
その証拠に、countupButtonを押すと、consoleにCountUpButton button mountedState trueと出力される。
またAppでbooをfalseにする(App setBooをclickする)と、CountUpButtonがunmountされるので、useEffect内のreturnが走り、falseがセットされるという流れ。

使用方法

公式のgithubのreadmeでは、mountされていないcomponentにたいして状態変更をしないようにするための関数と記述がある。
useEffect内でrefにtrueを代入しているので、初回renderの画面上はfalseだがrefにはtrueが入っているので、今回のonClickのように関数などにuseMountedStateを使用するのが良いのかもしれない。

Discussion

ログインするとコメントできます