LoginSignup
5
2

公式ドキュメントでつかんだReactの核心Part2 ~Context編~

Posted at

はじめに

どうもこんにちは!僕は現在1ヵ月本気の技術力向上を目指している現役高校生1年生です!
今回は前回の記事に引き続き、僕がReactで躓いたところを解説していきたいと思います。Context編、ぜひお楽しみあれ

Contextってなに?

そもそもContextって何だろうと思って調べてみました。
こちらの記事がとてもわかりやすかったです。この段階ではコンテキスト(Context 以降カタカナで記述します)の語義を理解して、コンテキストの仕様を府に落とすことが大事かなと思います。
僕はこういう語源から入るの好きなタイプです。でも英語話者からしたら当たり前なのか笑

コンテキストの仕様を簡易的に理解する

ReactではContextは、コンポーネント分割によりコードが複雑になってしまった場合に状態管理を便利にしてくれるものです。


コンテキストが必要になってくる流れを簡単にまとめると、

  1. コンポーネントを分割する・増やす
  2. ネストが深くなっていく
  3. Propsを渡す回数が多くなってくる
  4. めんどくさくなってくる笑
  5. コンテキスト使おう!!

とまぁこんな感じです.

コンテキストを一言で表すとグローバルな状態管理をしてくれる機能です。
Context = 機能ということではありませんが、だいだいこんなイメージをつかめていればOK!次の手順を読めば理解が深まるかもです。

Contextの使い方♪

1.Contextを生成しよう
コンテキストは言わば状態を管理する変数。

export const Context = createContext(初期値);

2.Contextに状態を渡そう

export const App = () => {
    return(
        <Context.provider value={渡したい値}>
            {/** いくつかのコンポーネント */}
        </Context.provider>
    );
}

このContext.providerで囲まれた子要素は、value="渡したい値"
をコンテキストとして受け取ることができる。どれだけネストされたコンポーネントであったとしても、

<コンテキスト名.provider>によって囲まれている、かつそれがコンポーネントにとって最も近いプロバイダー(provider)である*

ならばvalueの値をコンテキストとして受け取ることが出来る。

--語義から考えるプロバイダーとは--
その語義のとおり、提供するものという意味です。プロバイダーでコンポーネントを囲むことによって、値を提供することが出来ます。

3.Contextを受け取ろう

const { Context } = useContext(UserContext);

useContextというhooksを使用することで、最も近いプロバイダーから提供されたコンテキストを参照することが出来るようになります。
これにて晴れてコンテキストを使用することが出来ます。思う存分状態使いましょう!!笑

コンテキストを使用する際の注意点

コンテキストを使う上で意識しておくべきことはずばり、プロバイダーによって渡されたvalue(コンテキスト)が変更された際にその値を使用しているコンポーネントは再レンダリングの対象となるということです。

それに加えて、Reactの再レンダリングが走る条件である、

その親コンポーネントがレンダリングされること

が悪さをしてきます。



言葉だけだとわかりにくいのでサンプルコードで考えてみましょう

const Context = createContext(初期値);
export const App = () => {
    return(
        <Context.provider value={渡したい値}>
            <SampleA />
        </Context.provider>
    );
SampleA.jsx
export const SampleA = () => {
    const Context = useContext();
    return(
        <>
            <p>{context}</p>
            {/**SampleBはコンテキストを使用しない*/}
            <SampleB />
        </>
    );
}

仮にこのようにプロバイダーにSampleAというコンポーネントが子要素として設定されているとします。
そのSampleAのコンポーネントの中身は、上記のように構成されています。

SampleBというコンポーネントはコンテキストの値を使用することはありませんが、SampleAがコンテキストを使用することでSampleBもまた、レンダリング対象になってしまいます。


memoを使用することでそれを解決することが出来ます。

SampleB.jsx
export const SampleB = memo(() => {
    return(
        <div>
            {/** 複雑な処理 */}
        </div>
    );
});

このようにすることで、SampleBは自身に渡されるprops(今回はない)が変更されない限り再レンダリングを走らないように設定することが出来ます。

終わりに

コンテキストについてもなれてしまえば簡単なので、グローバルな状態管理の便利さを体感してみましょう!!
さらにRecoilというものを使えばもっと簡単にグローバルな状態管理を実装することが出来ます。気になる方はぜひ知らべてみてください!

参考

About Me

5
2
0

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
5
2