Best way to use conditional for useContext in React?

6.1k views Asked by At

I have a CommonChild component that called in two components: Parent1 and Parent2.

Bold Parent1 and Parent2 are use different AppContext.

Please look some simple code below:

import React, { useState, useContext, createContext } from 'react'

//Create two createContext of Parents
const ContextParent1 = createContext();
const ContextParent2 = createContext();

//Create two providers of Parents
const AppProviderParent1 = (props) => {
    const [state] = useState("This is AppProviderParent1")
    return (
        <ContextParent1.Provider value={state}>
            {props.children}
        </ContextParent1.Provider>
    )
}
const AppProviderParent2 = (props) => {
    const [state] = useState("This is AppProviderParent2")
    return (
        <ContextParent2.Provider value={state}>
            {props.children}
        </ContextParent2.Provider>
    )
}

//Two parents called CommonChild, but different AppProvider (created above)
const Parent1 = (props) => {
    return (
        <AppProviderParent1 {...props}>
            <CommonChild />
        </AppProviderParent1>
    )
}
const Parent2 = (props) => {
    return (
        <AppProviderParent2 {...props}>
            <CommonChild />
        </AppProviderParent2>
    )
}

//CommonChild that try to use useContext to get value
const CommonChild = () => {
    const context = useContext(...) //how to use useContext?
    return (
        <p>This is CommonChild Component</p>
    )
}

I don't know how to use useContext in CommonChild which sensibly.

Thank you for your help

1

There are 1 answers

1
Sapinder Singh On

Method 1

You can pass down an identifier to CommonChild that tells who is calling it. Then use the conditional operation ? like so-

const Parent1 = (props) => {
    return (
        <AppProviderParent1 {...props}>
             
            {/********** Pass down the caller string **********/}
            <CommonChild caller='parent1' />
        </AppProviderParent1>
    )
}
const Parent2 = (props) => {
    return (
        <AppProviderParent2 {...props}>
            
        {/********** Pass down the caller string **********/}
            <CommonChild caller='parent2' />
        </AppProviderParent2>
    )
}

//CommonChild that try to use useContext to get value
const CommonChild = ({caller}) => {
    const context = 
        useContext(caller === 'parent1' ?  AppProviderParent1 : AppProviderParent2);
    return (
        <p>This is CommonChild Component</p>
    )
}

Method 2

As you stated in the comment, you have multiple contexts and children as well. For this, you can put all the contexts in an array, and pass a number to the child component indicating the index of the context to use.

const appProviders = [AppProviderParent1, AppProviderParent2];

const Parent1 = (props) => {
    return (
        <AppProviderParent1 {...props}>
             
            {/********** Pass down index of AppProvider **********/}
            <CommonChild providerIndex={0} />
        </AppProviderParent1>
    )
}
const Parent2 = (props) => {
    return (
        <AppProviderParent2 {...props}>
            
        {/********** Pass down index of AppProvider **********/}
            <CommonChild providerIndex={1} />
        </AppProviderParent2>
    )
}


const CommonChild = ({providerIndex}) => {

    const context = 
        useContext(appProviders[providerIndex];
    return (
        <p>This is CommonChild Component</p>
    )
}

This way, you can pass the relevant Context to any child you want.