React:如何使用相同类型的多个上下文,同时允许孩子从所有上下文中读取数据

Posted

技术标签:

【中文标题】React:如何使用相同类型的多个上下文,同时允许孩子从所有上下文中读取数据【英文标题】:React: How to use multiple Contexts of the same type while allowing children to read data from all of them 【发布时间】:2021-10-08 21:03:51 【问题描述】:

我有一个类似的上下文设置

const DataContext = createContext( data: null );

const getData = (key) => 
    switch(key) 
        case 1:
            return "Hello"
        case 2:
            return " World"
        default:
            return null
    


export const DataProvider = ( id, children ) => 

  const data = useMemo(() => 
    return getData(id);
  , [id]);

  return (
    <DataContext.Provider
      value=
        data,
      
    >
      children
    </DataContext.Provider>
  );
;

export default DataContext

以及像这样使用它的子组件

const HelloComponent = () => 
    return <DataProvider id=1>
        
            // children are components that useContext(DataContext) and expect data to be "Hello"
        
    </DataProvider>


现在我需要这样做

const HelloWorldComponent = () => 
  return (
    <DataProvider id=1>
      <DataProvider id=2>
        
          // children are components that need to read both Hello and World
        
      </DataProvider>
    </DataProvider>
  );
;

需要将一个上下文定义的所有父上下文的数据提供给一组孩子

我知道 useContext 只能读取给定 ContextType 的最近父级,所以我不确定如何继续。

【问题讨论】:

【参考方案1】:

您不能使用两个相同类型的上下文提供程序并让孩子从两者接收。 Context API 使得子组件从 React 树中离它们最近的上下文提供者接收上下文值。

但是,您可以使用返回 getData 函数的单个提供程序。这是一个使用单个 DataProvider 和自定义 React 钩子来提供“id”值的示例。

Data.Context.js

import  createContext, useContext  from "react";

const DataContext = createContext(
  getData: () => 
);

const getData = (key) => 
  switch (key) 
    case 1:
      return "Hello";
    case 2:
      return " World";
    default:
      return null;
  
;

export const useDataContext = (id) => useContext(DataContext).getData(id);

const DataProvider = ( children ) => 
  return (
    <DataContext.Provider value= getData >children</DataContext.Provider>
  );
;

export default DataProvider;

index.js

<DataProvider>
  <App />
</DataProvider>

子组件

import  useDataContext  from "./Data.Context";

const Child = () => 
  const data1 = useDataContext(1);
  const data2 = useDataContext(2);

  return (
    <div>
      <div>DataProvider 1: data1</div>
      <div>DataProvider 2: data2</div>
    </div>
  )

【讨论】:

这很聪明,当然我要模拟的上下文比我提供的示例要复杂一些,但这实际上是一个解决方案,谢谢 @graren 谢谢。如果此答案解决/解决了您的问题,那么我邀请您接受它,否则,如果您发现它有帮助和/或有用,那么不要忘记也投票。如果您对更具体的用例有任何后续问题,请提出一个新问题并参考这个问题,并随时在此处向我发送链接,我可以查看。干杯。 我通过钩子返回我需要的上下文中的函数,使用了一个小的变体,不得不做出一些重构魔法,但它起作用了。已接受答案! createContext 中包含getData: () =&gt; 的目的是什么?我删除了它,它也可以工作.. ? @gordie 这是一个default context value,如果您尝试在上下文提供程序外部访问上下文值时使用。这不是必需的,但有时可以更轻松地处理代码。

以上是关于React:如何使用相同类型的多个上下文,同时允许孩子从所有上下文中读取数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 react-apollo 使用相同的查询进行多个 graphql 查询?

React - 上下文提供程序中的多个不相关值

我是不是允许在 OpenGL 2.1 的多个共享上下文中同时从同一个缓冲区对象进行渲染?

如何在 React Native 中使用 Animated API 同时隐藏 Header 和 Footer

使用相同的鼠标输出(同时)在多个 HTML CANVAS 中绘制

React - 如何使用上下文从对象中应用多个值