#reactjs #react-hooks #use-context
#reactjs #реагирующие хуки #использовать-контекст
Вопрос:
У меня есть CommonChild
компонент, который вызывается в двух компонентах: Parent1
и Parent2
.
Жирный Parent1
и Parent2
используется по-разному AppContext
.
Пожалуйста, посмотрите простой код ниже:
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>
)
}
Я не знаю, как разумно использовать useContext
в CommonChild
which.
Спасибо за вашу помощь
Комментарии:
1. Вы создаете единый контекст
const MyContext = createContext(<Default value here>);
, а затем создаете поставщиков для контекста в каждом из ваших родителей, изменяяvalue
предоставляемое вами свойство. Затем вы используете контекст в дочернем элементе путем вызоваconst context = useContext(MyContext)
, и он получит наиболее релевантный родительский контекст или значение по умолчанию, если родительский контекст не найден.2. Ох. Вы имеете в виду, что оба
AppProviderParent1
иAppProviderParent2
могут использовать одно и то жеcreateContext
?3. Да, если нет разницы между свойствами, которые они содержат. т.Е. Родительский элемент 1 может предоставлять значения
{ propA: true}
, а родительский элемент 2 может предоставлять значения поставщика{ propA: false}
4. Я попробую. Спасибо
5. Вот пример https://stackblitz.com/edit/react-ts-jheevm?file=index.tsx . Примечание: используется typescript
Ответ №1:
Способ 1
Вы можете передать идентификатор CommonChild
, который сообщает, кто его вызывает. Затем используйте условную операцию ?
следующим образом-
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 =
caller === useContext('parent1' ? AppProviderParent1 : AppProviderParent2);
return (
<p>This is CommonChild Component</p>
)
}
Способ 2
Как вы указали в комментарии, у вас также есть несколько контекстов и дочерних элементов. Для этого вы можете поместить все контексты в массив и передать число дочернему компоненту, указывающему индекс используемого контекста.
const appProviders = [AppProviderParent1, AppProviderParent2];
const Parent1 = (props) => {
return (
<AppProviderParent1 {...props}>
{/********** Pass down index of AppProvider **********/}
<CommonChild providerIndex='1' />
</AppProviderParent1>
)
}
const Parent2 = (props) => {
return (
<AppProviderParent2 {...props}>
{/********** Pass down index of AppProvider **********/}
<CommonChild providerIndex='2' />
</AppProviderParent2>
)
}
const CommonChild = ({providerIndex}) => {
// Remember to subtract 1 from providerIndex
const context =
caller === useContext(AppProviders[providerIndex - 1];
return (
<p>This is CommonChild Component</p>
)
}
Таким образом, вы можете передать соответствующий контекст любому дочернему элементу, который вы хотите.
Комментарии:
1. Мне это не нравится, потому что у меня много дочерних элементов, используемых в обоих родительских компонентах