Является ли значение контекста общим для экземпляров Provider из одного и того же контекста в React?

У меня есть компонент Provider, значения которого я экспортирую с помощью ловушки.

Простая реализация того, что я описываю, такова:

// SomeProvider.jsx
const SomeContext = React.createContext(null);

function SomeProvider(props) {
  const [state, setState] = useState(null)

  useEffect(() => {
    //some logic
    setState(newValue)
  }, [props.someValue])

  return <SomeContext.Provider value={state} {...props} />;
}

const useSome = () => React.useContext(SomeContext);

export { SomeProvider, useSome };

А что, если я захочу использовать этого поставщика контекста более чем в одном месте? Например

// App.jsx
<SomeProvider someValue={valueOne}>
  <SomeComponent />
</SomeProvider>
<SomeProvider someValue={valueTwo}>
  <SomeOtherComponent />
</SomeProvider>

где valueOne и valueTwo могут быть изменены

// SomeComponent.jsx
import { useSome } from 'SomeProvider';

function SomeComponent() {
  const someValue = useSome();

  return ....
}
// SomeOtherComponent.jsx
import { useSome } from 'SomeProvider';

function SomeOtherComponent () {
  const someValue = useSome();

  return ....
}

Приведет ли такой подход к тому, что два SomeProvider экземпляра будут иметь общее значение, что приведет к путанице?

Если это так, то каков будет правильный подход, чтобы каждый SomeProvider имел свое собственное «частное» значение?

Если это не так, как это работает, поскольку все поставщики являются производными от одного и того же вызова React.useContext()?


person Dimitris Karagiannis    schedule 16.11.2019    source источник
comment
Вы пробовали? Я на 99% уверен, что они не будут разделять ценности, поскольку они предоставляют два разных контекста.   -  person azium    schedule 16.11.2019
comment
Я думаю, что они будут иметь одно и то же значение, поскольку они получены из одного и того же React.createContext() (он выполняется только один раз в модуле). Я сделаю короткую демонстрацию и вернусь с ответами   -  person Dimitris Karagiannis    schedule 16.11.2019
comment
Я прав. только что протестировал его codesandbox.io/s/delicate-mountain-khig9   -  person azium    schedule 16.11.2019


Ответы (1)


Несмотря на то, что createContext вызывается только один раз, React создает экземпляры этих контекстов при рендеринге поставщика контекста. Когда что-то вызывает useContext, React поднимается по дереву рендеринга, чтобы найти ближайшего провайдера данного типа и получить эти значения из экземпляра этого контекста.

Пример

person azium    schedule 16.11.2019
comment
Итак, если я понял это правильно, с точки зрения непрофессионала, createContext(value) просто передает свой value каждому новому экземпляру Provider в качестве начального значения, но после этого каждый экземпляр полностью изолирован друг от друга. - person Dimitris Karagiannis; 16.11.2019
comment
Верно. Для большей ясности, опора value в компоненте Context.Provider не является обязательной. Вы использовали его, чтобы реализовать способ изменения значения по умолчанию, переданного в createContext, но то, что вы только что сказали, полностью верно. - person azium; 16.11.2019