React.createContext 如何从单个上下文创建多个实例?

Ger*_*áth 8 javascript reactjs

考虑我的例子:

const itemStructure = {
  a: [ "d", "c" ],
  b: [ "e", "f" ]
};

const Context = React.createContext({
  setId: () => {}, getId: null, providerId: null
});

const InnerItem = ({ id }) => {
  const value = React.useContext(Context);
  const setItem = () => value.setId(id);

  console.log(value);

  return <button onClick={setItem}>{id}</button>;
};

const OuterItem = ({ providerId }) => {
  const [ getId, setId ] = React.useState(null);

  return (
    <Context.Provider value={{ getId, setId, providerId }}>
      {itemStructure[providerId].map(id => <InnerItem id={id} key={id} />)}
    </Context.Provider>
  );
};

const App = () => {
  return Object.keys(itemStructure).map(id => (
    <OuterItem providerId={id} key={id} />
  ));
};

ReactDOM.render(<App />, document.getElementById('root'));
Run Code Online (Sandbox Code Playgroud)
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

单击每个按钮后,查看控制台记录的内容作为providerId。它记录了正确的值,但我不明白为什么。我希望它不起作用,因为无论哪个 OuterItem 使用它,它都将是相同的 Context,并且它们共享它。

所以我的问题是多个组件如何在同一上下文上共享,但由提供者使其相同?

Fue*_*ter 10

当您调用 时createContext,您并没有创建实例,您只是创建了一种新类型的上下文。

因此,当您调用时,<TypeContext>.Provider您正在创建一个实例,所有组件都位于该类型的上下文实例内。因此,无论什么组件使用此上下文,都会发现上下文类型更接近。

一些例子:

const OneTypeContext = React.createContext('hello world')
Run Code Online (Sandbox Code Playgroud)
const WorldOne = () => {
  const value = useContext(OneTypeContext)

  console.log(value)
}
Run Code Online (Sandbox Code Playgroud)
<OneTypeContext.Provider>
  <WorldOne />
</OneTypeContext.Provider>

// console.log(value) => `hello world`
Run Code Online (Sandbox Code Playgroud)

但是,如果您将与新实例相同的上下文类型放入相同上下文的其他实例中,则类似函数useContext将几乎找到上下文。前任:

<OneTypeContext.Provider>
  <OneTypeContext.Provider value="Hello Other World">
    <WorldOne />
  </OneTypeContext.Provider>
</OneTypeContext.Provider>

// console.log(value) => `Hello Other World`
Run Code Online (Sandbox Code Playgroud)

参考: https: //reactjs.org/docs/context.html#api