如何动态地将 React Web 组件添加到父组件?
How can I add React web components to a parent component dynamically?
假设我有一堆 React 网络组件
const ComponentA = () => {
return (<div>A</div>)
}
const ComponentB = () => {
return (<div>B</div>)
}
const ComponentC = () => {
return (<div>C</div>)
}
const ComponentD = () => {
return (<div>D</div>)
}
const ComponentE = () => {
return (<div>E</div>)
}
我有一个父组件可以渲染其中的一些。
export default function () {
const [state, setState] = useState({ count: 0, initialized: false, components: [ComponentA, ComponentB, ComponentC] });
return (
<FlexLayout>
{state.components.map((comp, i) => React.createElement(comp, { key: i }))}
</FlexLayout>
);
}
这是有效的,因为我可以看到我的三个组件 A、B 和 C 已正确呈现。接下来,我添加一个按钮来动态添加新项目。
export default function () {
const [state, setState] = useState({ components: [ComponentA, ComponentB, ComponentC] });
const handler = () =>
{
const list = state.components.slice(0);
list.push(ComponentD);
setState ({ components : list })
}
return (
<FlexLayout>
<button onClick={() => setState(handler)}>Add Component</button>
{state.components.map((comp, i) => React.createElement(comp, { key: i }))}
</FlexLayout>
);
}
这在我第一次点击按钮时也有效。我可以看到我已经添加了 ComponentD 。但是,如果我尝试再添加一个 ComponentD 实例,应用程序会崩溃并出现以下错误:
是什么导致我的组件不再对父级可用的范围丢失?
一些反馈:
- 将整个组件存储在状态中是一种反模式。相反,将 ID 存储在状态中。更简单的状态将减少错误的可能性。
- 正如 @Mary 所说,您的处理程序分配不正确。
这是一个工作示例:
const ComponentA = () => {
return (<div>A</div>)
}
const ComponentB = () => {
return (<div>B</div>)
}
const ComponentC = () => {
return (<div>C</div>)
}
const ComponentD = () => {
return (<div>D</div>)
}
const componentMap = {
a: ComponentA,
b: ComponentB,
c: ComponentC,
d: ComponentD,
}
export default function () {
const [components, setComponents] = useState([
'a','b','c',
]);
const handler = () => {
setComponents ( [...components, 'd'] );
}
return (
<FlexLayout>
<button onClick={handler}>Add Component</button>
{components.map(ID => {
const Component = componentMap[ID];
return <Component key={ID}/>
})}
</FlexLayout>
);
}
假设我有一堆 React 网络组件
const ComponentA = () => {
return (<div>A</div>)
}
const ComponentB = () => {
return (<div>B</div>)
}
const ComponentC = () => {
return (<div>C</div>)
}
const ComponentD = () => {
return (<div>D</div>)
}
const ComponentE = () => {
return (<div>E</div>)
}
我有一个父组件可以渲染其中的一些。
export default function () {
const [state, setState] = useState({ count: 0, initialized: false, components: [ComponentA, ComponentB, ComponentC] });
return (
<FlexLayout>
{state.components.map((comp, i) => React.createElement(comp, { key: i }))}
</FlexLayout>
);
}
这是有效的,因为我可以看到我的三个组件 A、B 和 C 已正确呈现。接下来,我添加一个按钮来动态添加新项目。
export default function () {
const [state, setState] = useState({ components: [ComponentA, ComponentB, ComponentC] });
const handler = () =>
{
const list = state.components.slice(0);
list.push(ComponentD);
setState ({ components : list })
}
return (
<FlexLayout>
<button onClick={() => setState(handler)}>Add Component</button>
{state.components.map((comp, i) => React.createElement(comp, { key: i }))}
</FlexLayout>
);
}
这在我第一次点击按钮时也有效。我可以看到我已经添加了 ComponentD 。但是,如果我尝试再添加一个 ComponentD 实例,应用程序会崩溃并出现以下错误:
是什么导致我的组件不再对父级可用的范围丢失?
一些反馈:
- 将整个组件存储在状态中是一种反模式。相反,将 ID 存储在状态中。更简单的状态将减少错误的可能性。
- 正如 @Mary 所说,您的处理程序分配不正确。
这是一个工作示例:
const ComponentA = () => {
return (<div>A</div>)
}
const ComponentB = () => {
return (<div>B</div>)
}
const ComponentC = () => {
return (<div>C</div>)
}
const ComponentD = () => {
return (<div>D</div>)
}
const componentMap = {
a: ComponentA,
b: ComponentB,
c: ComponentC,
d: ComponentD,
}
export default function () {
const [components, setComponents] = useState([
'a','b','c',
]);
const handler = () => {
setComponents ( [...components, 'd'] );
}
return (
<FlexLayout>
<button onClick={handler}>Add Component</button>
{components.map(ID => {
const Component = componentMap[ID];
return <Component key={ID}/>
})}
</FlexLayout>
);
}