I have a use-case where I want to store a list of components in the state of a useState()
hook.
So far, this works for about 50%. I can properly store and render the components, but they are not updated properly. They do not seem to register state changes that are outside of the components themselves. Consider the following example:
function Test(): ReactElement {
const [elements, setElements] = useState<Array<() => ReactNode>>([]);
const [count, setCount] = useState(0);
return (
<div>
<Input type="button" children="+" onClick={() => setCount(count + 1)} />
<Input type="button" children="Add" onClick={() => setElements([...elements, () => <div>{count}</div>])} />
{elements.map((Element, index) => (
<Element key={index}
))}
</div>
);
}
This component does the following things:
- It has a list of elements, created by the first
useState()
hook. - It has a counter, created by the second
useState()
hook. This counter can be increased using the firstInput
(the'+'
one) component. - It has an
Input
labeled'Add'
, which adds a new element to the list in the state. - It renders each of the elements in the state. Every one of these elements displays the counter.
As I said, this works fine, except that the elements from the state will display the counter value that they were created with and they will never update, even when they should after the counter was.
Is there a way to fix this, so that the elements will be updated in the expected manor?
Full/Further Context:
I am in the midst of writing a UI framework where each page has a headerbar and content (plus a couple of other things that I have omitted for the sake of simplicity). I want to be able to add elements to the headerbar from within the content (both of which are naturally different components), i.e. something like this:
<Page>
<Headerbar>
// Headerbar Elements, dynamically created
</Headerbar>
<Content>
// Other components that make up the content
</Content>
</Page>
My current idea is to use a system like above where I store the elements in a state from where they can then be rendered in the headerbar. However, if someone has a better way of achieving that, I am open to suggestions (hence this further context).