Reactの最も一般的な間違い

UnsplashのCHUTTERSNAPによる写真

Reactアプリケーションで解決する必要がある最も一般的な問題の1つは、外部データのフェッチです。一般に、これは解決方法を学ぶ最初の問題の1つですが、ほとんどの実装では、マウントされていないコンポーネントの状態を更新するという1つの単純な間違いがあります。

非常に簡単な例から始めます。投稿に関連するデータをフェッチし、フェッチの進行中に読み込みメッセージを表示し、エラーの場合はエラーを表示し、別の場合はリストを表示するブログコンポーネントです。ポストの。

const Blog = () => {
  const [posts, setPosts] = useState([]);
  const [status, setStatus] = useState('idle');
  const [error, setStatus] = useState(null);
useEffect(() => {
    const fetchData = async () => {
      setStatus('loading');
      try{
        setStatus('loading');
        const posts = await getAllPosts();
        setPosts(posts);
        setStatus('finished');
       } catch(e) {
         setStatus('error');
         setError(e);
       }
    }
  }, []);
if(status == 'error') return <p>Error while loading data</p>;
  if(status == 'loading') return <p>Loading...<p>;
  return <PostGrid posts={posts} />
};

このgetAllPosts関数は待機中の非同期関数です。この関数が戻るまでに数秒かかる場合があり、戻ったときにコードがsetPosts関数を呼び出そうとしますが、この瞬間より前にコンポーネントがマウント解除された場合はどうなりますか?マウントされていないコンポーネントの状態を設定できないため、警告が表示されます。

const posts = await getAllPosts();
setPosts(posts);  # Warning: Can't perform a React state update on an unmounted component.
setStatus('finished');

重要なのは、コンポーネントがマウントされている場合にのみ状態を設定することです。この場合、getAllPostsが呼び出された後にコンポーネントがマウントされていることを確認する必要があります。そのために、現在のコンポーネントがマウントされているかどうかを確認するメカニズムを抽象化するフックを使用します。

const useIsMounted = () => {
  const isMounted = React.useRef(false);     // (1)
  React.useEffect(() => {
    isMounted.current = true;                // (2)
    return () => isMounted.current = false;  // (3)
  }, []);                                    // (3)
  return isMounted.current;
}

これで、元のコンポーネントで使用できます

const Blog = () => {
  const [posts, setPosts] = useState([]);
  const [status, setStatus] = useState('idle');
  const [error, setStatus] = useState(null);
  const isMounted = useIsMounted();
useEffect(() => {
    const fetchData = async () => {
      setStatus('loading');
      try{
        const posts = await getAllPosts();
        if(isMounted) {
          setPosts(posts);                    // 1
          setStatus('finished');
        }
} catch(e) {
          if(isMounted) {
            setStatus('error');               // 2
            setError(e);
          }
       }
    }
  }, []);
if(status == 'error') return <p>Error while loading data</p>;
  if(status == 'finished') return <PostList posts={posts} />
  return <p>Loading...<p>;
};

結論

マウントされていないコンポーネントの状態を更新しようとすることは、reactsアプリで非常に一般的な問題です。この問題は通常、外部データをフェッチするときに発生しますが、その後の状態の変化をトリガーする非同期イベントを使用するときにも同じ問題が発生します。その完成。

読んでくれてありがとう!

これでこの投稿は終わりです。内容がお好みに合っていることを願っています。次の投稿でお会いしましょう。

PlainEnglish.ioでより多くのコンテンツ。無料の週刊ニュースレターにサインアップしてください。TwitterとLinkedInでフォローしてください。私たちのコミュニティDisc​​ordに参加してください。

提案された投稿

ドメイン名に関する情報の検索

Brian P. Hogan 著『Small, Sharp Software Tools』からの抜粋

ドメイン名に関する情報の検索

facebook.com にリクエストを送信すると、コンピュータはドメイン名を検索してそのドメイン名を IP アドレスに変換し、コンピュータが接続できるようにします。

地球を救ってお金を稼ぐ方法

地球を救ってお金を稼ぐ方法

ペットボトル、ガラス瓶、アルミ缶、グリーンエネルギーパッケージなどを、何回考えずに捨てたことがあるでしょうか? リサイクルする代わりに何かが得られたらいいのにと何度思ったことか。あなたがほとんどの人と同じなら、おそらく答えは何度もあるはずです。リサイクルは、多くの場合、即時的または具体的な利益をもたらさない面倒な作業、面倒な作業、または義務であると考えられています。

関連記事

ジャーナル・アウトバート

ジャーナル・アウトバート

日記を開く: 1 日 1 枚の写真。私はいつも物語に魅了されてきました。

その脅威アーカイブ: Vol 7 ブラックバスタ

その脅威アーカイブ: Vol 7 ブラックバスタ

今日の相互接続された世界では、サイバー攻撃の脅威がかつてないほど蔓延しています。サイバー犯罪者や国家主体は常に脆弱性を悪用して貴重なデータを盗もうとしており、あらゆる規模の組織に重大なリスクをもたらしています。

お子様向けの初めてのハイになる本

お子様向けの初めてのハイになる本

(警告 - これは風刺であり、大喜びで破壊的な意図があります - 絶対に子供向けではありません) あなたは、お母さんとお父さんがキッチンに隠れて臭いタバコを吸っているのを見たことがあるでしょう。彼らはあなたに言います。

カウボーイの嘘

巨大企業はいかにしてアメリカ国民にひどい嘘を売ったのか

カウボーイの嘘

西のなだらかな丘陵地帯では、太陽の最初の光が平原の曇った草を照らす、まばゆいばかりの金色の朝です。真っ黒で巨大な穏やかなアンガス牛の群れが日の出を背景にシルエットを描き、誰もがよく知っている場所へ人里離れた道を進んでいます。朝食バー。