Let's say I have a bunch of React web components
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>)
}
and I have a parent component that renders some of them.
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>
);
}
This works as I can see my three components A, B, and C are rendered properly. Next, I add a button to add new items dynamically.
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>
);
}
This also works when I click the button for the first time. I can see that I have added ComponentD . However, If I try to add one more instance of ComponentD the app crashes with the following error:
What is causing this loss of scope where my components are no longer available to the parent?
Some feedback:
Here's a working example:
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>
);
}