反応フックを解明する


反応フックは、機能的な構成要素がユーザーインターフェースでstatefulなふるまいと副作用をカプセル化するより簡単な方法で彼らを提供する方法を変えました.いくつかのフックが理解し、他の人よりも使用するように簡単ですので、投稿のこのシリーズは、簡単ではないフックの解明に焦点を当てます.
これまでのところ、usecallback、usememo、userefを深さで調べました.このポストはプロップのドリルとコンテキストの違いを探ることから始めます.続いてコンテキストオブジェクトを定義し、usecontext () hookの使い方を説明し、そのパフォーマンスを最適化する方法を説明します.

支柱掘削対文脈



反応は、親コンポーネントが子とデータを共有するために親コンポーネントを使用するデータフローを提供します.データを追跡するこの方法は、小さなアプリケーションのために素晴らしい作品、しかし、あなたのアプリケーションが成長すると、自分自身がコンポーネントの複数の層を介して小道具を通過見つけるかもしれません.これを支柱掘削と呼ぶ.
複数の層を介して小道具を通過するとき、データが初期化されているか、データが実際に使用されているかを識別すると、非常にチャレンジングで面倒になることができます.そのうえ、あなたのコードをリファクタリングすることは不必要な小道具を通過するか、1つの小道具(別名バグ!)のために複数の名前を使用することにつながるかもしれません.
プロップドリルの代替としては、コンテキストを使用することです.単純な、軽い解決策で、親と子の関係がない場合でも、コンポーネント間でデータにアクセスできるようになります.

文脈オブジェクトとは


コンテキストオブジェクトはcreateContext() APIとその2つの要素で構成されます.
プロバイダ:値を提供します
消費者:価値を消費する
コンテキストオブジェクトを作成するには、空または値を初期化できます.
const testContext = createContext();
そして、この方法で破壊することによって、その要素にアクセスできます.
const { Provider, Consumer } = testContext;

どのようにプロバイダを使用するには?


The Provider コンテキストオブジェクトでは、コンポーネントツリーの親要素をラップする必要があります.これは、コンポーネントツリーツリーの下にグローバルデータにすべてのコンポーネントを与えます.この動画を見る<Provider> 下記のタグ、彼らはname ラップされているすべてのコンポーネントにアクセス可能な状態.さて、コンポーネント<NameModifier /> and <NamePrinter /> (そして、彼らの子供のいずれか)州へのアクセスがあるname たとえ合格していないとしてもname 小道具として.
const App = () => {
  const { Provider } = testContext;
  const [name, setTestName] = useState(Milu);

  return (
    <Provider value={{ name }}>
      <NameModifier />
      <NamePrinter />
    </Provider>
  );
};

usecontext ()を使用してグローバルデータにアクセスする方法は?


usecontext () hookは、コンテキストオブジェクト(上記で定義されている)を受け入れ、プロバイダーが静的変数として利用できる現在の値を返します.
ここに我々の<NamePrinter /> コンポーネント(コードの前のセクションのプロバイダタグによって包まれます)、そして、私たちは値0にアクセスしていますname を使用してuserContext() フック.
export const NamePrinter = () => {
    const { name }  = useContext(testContext);

    return <div>My name is {name}!</div>
};

Did you notice how <NamePrinter /> is not taking any props? The name value is being accessed using the useContext() hook instead.


どのように、私は私の前後関係を更新しますか?


また、あなたのプロバイダを介して機能を利用できるようにすることができます!
次の例では、updateName() これにより、name 状態.あなたが見ているならば<NameModifier /> コンポーネント、私はupdateName() usecontextフックを使って関数を入力し、入力を変更するたびに呼び出します.

どのようなパフォーマンスについて?


コンテキストオブジェクトの値が更新されると、usecontext ()を使用するコンポーネントが再描画されます.コンテキスト内の値の1つが非常に頻繁に変更されるインスタンスに実行することができます.これにより、変更された値が小さいコンポーネントツリーでのみ使用されているにもかかわらず、すべてのコンポーネントがusecontext ()を再描画する原因となります.
推奨する解決策は、コンテキストを分割することです.したがって、あなたがライト/ダークのテーマを持っている場合、それらの間で選択するトグルは、おそらくあなたのコンテキストで共有されている他の値と比較してあまり頻繁に変更されません、あなたはThemeContext and AppContext 下記の通り.
const App = ({ user, theme, themeToggle }) => {

  return (
    <ThemeProvider value={{ theme, themeToggle }}>
      <AppContext value={{ user }}>
        <HomePage />
      </AppContext>
    </ThemeProvider>
  );
};

概要


コンテキストオブジェクトの使用は、プロップの穴あけに大きな代わるものです.それはあなたが小道具としてそれを渡すことなく、グローバルデータにアクセスすることができますし、それが変更時に再レンダリングするためにサブスクライブします.
contextオブジェクトには2つの要素があります.Provider and Consumer .
The Provider 要素はグローバルデータにアクセスできるコンポーネントツリーをラップする必要があります.
usecontext () hookは、Provider ラッパー.
不要な再レンダリングを避けるために、コンテキストを分割します.使用ThemeContext and AppContext .
私はusecontext ()のこの説明が役に立ち、将来のアプリケーションでこれらの新しい概念を適用することを望みます!
私は毎週新しいコンテンツを投稿します.我々は、次の週末に異なる反応フックを探索しています.私に従って、新しい記事に追いつくために!