並行して18の新しいフックを反応させてください!


同時性は重要な変化であるReact 18 .
次のフックを見ます.
  • useId UseIDは、両方のクライアントとサーバー上のユニークなIDを生成するための新しいフックの不一致を回避しながらです.これは主に、固有のIDを必要とするアクセシビリティAPIを統合するコンポーネントライブラリに便利です.これは、すでに反応17と下に存在する問題を解決します、しかし、新しいストリーミングサーバレンダラがどのようにHTMLをオーダーアウトするかについて、反応18でさらに重要です.See docs here.
  • useTransition UseTransitionとStartTransitionでは、いくつかの状態更新を緊急ではなくマークします.他の州の更新はデフォルトで緊急と見なされます.反応は、緊急の状態更新(例えば、テキスト入力を更新する)が非緊急の状態更新(例えば、検索結果のリストを描く)を中断するのを許します.See docs here
  • useDeferredValue UseDeferredValueを使用すると、ツリーの非緊急部分を再レンダリングすることができます.それは、ディベートに似ていますが、それに比べていくつかの利点があります.一定の遅延時間がないので、最初のレンダリングが画面に反映された後、Referred Request Rightを試みます.遅延されたレンダリングは割り込み可能で、ユーザー入力をブロックしません.See docs here.
  • これらのフックをコードで説明します.完全には.
    私はちょうどあなたに簡単なビューを与えたい.
    あなたがより詳細を知りたいならば、Googleはそれのために、そして、あなたは多くの材料をオンラインで見つけることができます.
    それを始める前にReactDOM.render 置換するcreateRoot .
    * createRoot : レンダリングするかアンマウントするルートを作成する新しいメソッド.代わりにreactdomを使用します.表示する.反応18の新機能はそれなしで動作しません.See docs here.
    私はちょうどそれを設定します.
    import React from 'react';
    import { createRoot } from 'react-dom/client';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    
    const container = document.getElementById('root') || document.body;
    const root = createRoot(container);
    root.render(
      <React.StrictMode>
        <App />
      </React.StrictMode>
    );
    
    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();
    

    USID


    あなたはuuid ノードを識別するためにuniqueidを生成します.
    今' useid 'を使用することができます.
    import React, {
      useState,
      useCallback,
      useMemo,
      useRef,
      useEffect,
      useId,
    } from 'react';
    
    interface TimerItem {
      id: string;
      createdAt: Date;
      tm: NodeJS.Timeout;
    }
    
    let num = 1;
    let count = () => {
      return num++ % 10000;
    };
    
    function Timer() {
      const [timers, setTimers] = useState<TimerItem[]>([]);
      const [workIn, setWorkIn] = useState(false);
      const id = useId(); // generate uniqueId
      const delUniqueId = useRef<string | null>(null);
    
      const toggle = useCallback(() => setWorkIn((prev) => !prev), []);
    
      const addTimer = useCallback(() => {
        // create new timer
        const itemId = `${id}${count()}`;
        const newItem = {
          id: itemId,
          createdAt: new Date(),
          tm: setTimeout(() => {
            const tmInv = setInterval(() => {
              if (!delUniqueId.current) {
                // insert this uniqueId into delUniqueId to remove and execute worker using toggle
                delUniqueId.current = itemId;
                toggle();
                // if delUniqueId is changed successfully, clear this timer
                clearInterval(tmInv);
              }
            }, 50);
          }, 2000),
        };
    
        setTimers((prevTimers) => [...prevTimers, newItem]);
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, []);
    
      useEffect(() => {
        if (!delUniqueId.current) return;
    
        // remove a timer by delUniqueId
        setTimers(timers.filter((t) => t.id !== delUniqueId.current));
        delUniqueId.current = null;
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, [workIn]);
    
      const children = useMemo<React.ReactNode>(() => {
        return (
          <>
            {timers.map((timer) => (
              <div key={timer.id}>
                <span>
                  Timer / {timer.id} / {timer.createdAt.getMinutes()}::
                  {timer.createdAt.getSeconds()}
                </span>
              </div>
            ))}
          </>
        );
      }, [timers]);
    
      return (
        <div>
          <button onClick={addTimer}>Add Timer</button>
          <hr />
          {children}
        </div>
      );
    }
    
    function App() {
      return (
        <>
          <Timer />
          <Timer />
          <Timer />
        </>
      );
    }
    

    それは3を貸すTimer . 各タイマーコンポーネントはUniqueIDを持ちます.データのIDを識別できます.
    あなたは見ました:R 1 ::R 3 ::R 5?
    はい、私はそれが良い例であるかどうかわからない.
    とにかく、あなたはuseId uniqueidを生成する.
    でも、どうぞ

    useId is not for generating keys in a list. Keys should be generated from your data.* See docs


    useTransition, startTransition


    緊急と他の州のアップデートではないとしていくつかの状態の更新はデフォルトで緊急と見なされますか?
    用途startTransition 非緊急状態の更新.
    import React, {
      useEffect,
      useState,
    } from 'react';
    
    const nodes: React.ReactNode[] = [];
    
    for (let i = 1; i <= 5000; i++) {
      nodes.push(<div>{Math.random() * i}</div>);
    }
    
    function App() {
      const [text, setText] = useState('');
      const [random, setRandom] = useState<React.ReactNode[]>([]);
    
      useEffect(() => {
        if (!text) return;
          setRandom(nodes);
      }, [text]);
    
      return (
        <>
          <input
            type="text"
            onChange={(e) => setText(e.target.value)}
            value={text}
          />
          <>{random}</>
        </>
      );
    }
    

    以下が例です.
    ご覧のように、私がタイプするとき、それはほとんどタイピングを止めました.
    他のコンポーネントのレンダリング(ランダム番号リストの下に)を考慮すると、このように' startTransition 'を使用できます.
    import React, { useEffect, useState, startTransition } from 'react';
    
    const nodes: React.ReactNode[] = [];
    
    for (let i = 1; i <= 5000; i++) {
      nodes.push(<div>{Math.random() * i}</div>);
    }
    
    function App() {
      const [text, setText] = useState('');
      const [random, setRandom] = useState<React.ReactNode[]>([]);
    
      useEffect(() => {
        if (!text) return;
        startTransition(() => {
          setRandom(nodes);
        });
      }, [text]);
    
      return (
        <>
          <input
            type="text"
            onChange={(e) => setText(e.target.value)}
            value={text}
          />
          <>{random}</>
        </>
      );
    }
    

    ビットストップ(他のコンポーネントはとにかくレンダリングする必要があります)が、それは確かに以前よりも良かった.
    何かを読み込む必要がある場合は、使用することができますuseTransition
    import React, { useEffect, useState, useTransition } from 'react';
    
    const nodes: React.ReactNode[] = [];
    
    for (let i = 1; i <= 5000; i++) {
      nodes.push(<div>{Math.random() * i}</div>);
    }
    
    function App() {
      const [text, setText] = useState('');
      const [random, setRandom] = useState<React.ReactNode[]>([]);
      const [isPending, startTransition] = useTransition();
    
      useEffect(() => {
        if (!text) return;
        startTransition(() => {
          setRandom(nodes);
        });
      }, [text]);
    
      return (
        <>
          <input
            type="text"
            onChange={(e) => setText(e.target.value)}
            value={text}
          />
          {isPending ? 'loading...' : <>{random}</>}
        </>
      );
    }
    

    使用法


    何かの変更は、他のレンダリングに影響を与える?
    しかし、あなたは何かの変化を最初に提出しなければなりません、そして、他がそれの後で続くことは大丈夫ですか?
    用途useDeferredValue .
    import React, { useState, useMemo } from 'react';
    
    function App() {
      const [text, setText] = useState('');
    
      const random = useMemo<React.ReactNode>(() => {
        const children: React.ReactNode[] = [];
    
        for (let i = 1; i <= 3000; i++) {
          children.push(<div>{Math.random() * i}</div>);
        }
    
        return children;
        // eslint-disable-next-line react-hooks/exhaustive-deps
      }, [text]);
    
      return (
        <>
          <input
            type="text"
            onChange={(e) => setText(e.target.value)}
            value={text}
          />
          <>{random}</>
        </>
      );
    }
    

    以下が例です.
    これは、テキストの変更に応じて3000のランダムなノードをレンダリングします.
    遅れがたくさんありますね.
    使いましょうuseDeferredValue
    import React, { useDeferredValue, useState, useMemo } from 'react';
    
    function App() {
      const [text, setText] = useState('');
      const deferredText = useDeferredValue(text);
    
      const random = useMemo<React.ReactNode>(() => {
        const children: React.ReactNode[] = [];
    
        for (let i = 1; i <= 1000; i++) {
          children.push(<div>{Math.random() * i}</div>);
        }
    
        return children;
      }, [deferredText]);
    
      return (
        <>
          <input
            type="text"
            onChange={(e) => setText(e.target.value)}
            value={text}
          />
          <>{random}</>
        </>
      );
    }
    


    deemredtextをusememoの依存関係として使用しました.
    それは、討論することに類似しています.

    結論


    反応18新しいフック!他の新機能です.
    私はあなたのプロジェクトにそれらを適用する前にGoogleをお勧めします.
    あなたのユーザーのための同時レンダリングであなたの戦略を確認します.React 別の権限を与えてくれた.
    ハッピーコーディング!