Javascript 重复使用包含上下文的组件

Javascript 重复使用包含上下文的组件,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我有一个内部使用上下文的复杂组件。例如: // ComplexComponent.tsx const MyContext = createContext({}); export function useMyContext() { return useContext(MyContext); } export default function ComplexComponent({ fooValue }) { return ( <MyContext.Provider valu

我有一个内部使用上下文的复杂组件。例如:

// ComplexComponent.tsx

const MyContext = createContext({});
export function useMyContext() {
  return useContext(MyContext);
}

export default function ComplexComponent({ fooValue }) {
  return (
    <MyContext.Provider value={{ foo: fooValue }}>
      <NestedComponent />
    </MyContext.Provider>
  );
}
//ComplexComponent.tsx
const MyContext=createContext({});
导出函数useMyContext(){
返回useContext(MyContext);
}
导出默认函数ComplexComponent({fooValue}){
返回(
);
}
//NestedComponent.tsx
从“./ComplexComponent”导入{useMyContext};
导出默认函数NestedComponent(){
const{foo}=useMyContext();
返回(
{foo}
);
}
是否有一种动态生成上下文的方法,以便我可以在代码中的其他位置重用该组件(同时有几个实例发生)


显然,我必须将
createContext
函数放在
ComplexComponent
中,但这样我就无法从
上下文导入
useMContext

上下文旨在共享可被视为React组件树的“全局”数据

据我所知,您的问题是,我不认为React
Context
支持您想要实现的目标

作为一种可能的替代方案,您可以定义一个setter函数,该函数可以从嵌套组件调用,但是:

//ComplexComponent.tsx
// ...
导出默认函数ComplexComponent({fooValue}){
const[foo,setFoo]=useState(fooValue);
返回(
);
}
然后将其设置为“动态”,如下所示:

//NestedComponent.tsx
// ...
导出默认函数NestedComponent(){
const{foo,setFoo}=useMyContext();
setFoo(“新Foo值”);
返回(
{foo}
);
}

这里需要注意的是,这将更新上下文中每个消费者的
foo
值。我认为,如果你想让不同的组件具有不同的
foo
值,你最好把
fooValue
作为
props
传递给它们,因为React的上下文是全局的,我甚至不想动态生成上下文

最后,我在
ComplexComponent
中使用了一个简单的状态,因为它被很好地封装,并允许使用我想要的
ComplexComponent
的任意多个独立实例


但是,这种解决方案有一个明显的缺点,就是将“上下文参数”向下传递到每个级别的子组件。

您能举一个这样的“重用”示例吗?这里的通用用法是什么?您的意思是希望能够动态创建自定义挂钩(如
useContext
)?所以你不能。如果您只是想创建上下文,那么您可以使用HOC.Ofc,您可以编写某种生成器(它将返回给定实例名称的自定义挂钩),但这是一种非常少见的模式。。。“我不会推荐的,谢谢你,”丹尼斯瓦什说。我有一个复杂的下拉列表,我只想对不同的数据重复使用它(就像我在我的示例中使用的
fooValue
),你想为每个新数据创建新的上下文吗?请在问题中举例说明。谢谢你的回答。但是,您的解决方案仍然不允许使用多个
ComplexComponent
,因为任何更新都会影响所有实例。很遗憾,对于您来说,最简单的方法可能是创建两个单独的上下文。
// NestedComponent.tsx

import { useMyContext } from './ComplexComponent';

export default function NestedComponent() {
  const { foo } = useMyContext();
  return (
    <div>
      { foo }
    </div>
  );
}