我有一个Parent
组件渲染Spawner
组件。Spawner
负责根据一定的条件显示child
组件。
我将Parent
包装在一个上下文中,因为创建的child
需要访问Parent
中的一些道具。
// Parent file
export const ParentContext = createContext({
prop1: '',
prop2: '',
})
const Parent = () => {
// An example condition
const condition = 'child1'
return (
<ParentContext.Provider value={{ prop1: 'prop1', prop2: 'prop2'}}>
{/* some other jsx */}
<Spawner type={condition} />
</ParentContext.Provider>
)
}
// Spawner file
const component = [
{ type: 'child1', Component: Child1 },
{ type: 'child2', Component: Child2 },
{ type: 'child3', Component: Child3 },
]
export const Spawner = ({ type }) => {
const ChildToDisplay = component.find((comp) => comp.type === type)?.Component || () => null;
return (
<>
<ChildToDisplay />
</>
)
}
子组件使用useContext
钩子
// in each child component, a useContext hook is called
const Child1 = () => {
const context = useContext(ParentContext)
return (
// some jsx
)
}
我得到一个错误:Cannot access 'Child1' before initialization.
如果我删除useContext
,错误得到解决。但是我需要上下文在子元素中有条件地呈现一些东西。
可能是因为张贴的都在一个文件中,Child1
可能在定义之前使用?
我尝试了代码,但在分开的文件中,它似乎是工作的,这里是一个快速演示的实验:
ParentContext.js
import React, { createContext } from 'react';
export const ParentContext = createContext({
prop1: '',
prop2: '',
});
Child1.js
import React, { useContext } from 'react';
import { ParentContext } from './ParentContext';
// in each child component, a useContext hook is called
const Child1 = () => {
const { prop1, prop2 } = useContext(ParentContext);
return <h1>{`${prop1} ${prop2}`}</h1>;
};
export default Child1;
App.js
import React from 'react';
import './style.css';
import Child1 from './Child1';
import { ParentContext } from './ParentContext';
const Parent = () => {
// An example condition
const condition = 'child1';
return (
<ParentContext.Provider value={{ prop1: 'Hello', prop2: 'World' }}>
{/* some other jsx */}
<Spawner type={condition} />
</ParentContext.Provider>
);
};
// Spawner file
const component = [
{ type: 'child1', Component: Child1 },
{ type: 'child1', Component: Child1 },
{ type: 'child1', Component: Child1 },
];
export const Spawner = ({ type }) => {
const ChildToDisplay =
component.find((comp) => comp.type === type)?.Component || (() => null);
return <>{ChildToDisplay && <ChildToDisplay />}</>;
};
export default function App() {
return (
<div>
<Parent />
</div>
);
}