Home > Software design >  React: Setting a state of type ReactNode crashes the application
React: Setting a state of type ReactNode crashes the application

Time:04-13

I want to dynamically render a component based on what the user has clicked. I tried something like this:

function ComponentTest() {
    const [component, setComponent] = useState<ReactNode | null>(null);


    return <button onClick={() => setComponent(SomeFunctionalComponent)}>Crash</button>
}

In this example I'm obviously not doing anything with the state, but clicking this button results in the application crashing with the following error messages:

Warning: Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see https://reactjs.org/link/rules-of-hooks
Warning: React has detected a change in the order of Hooks called by EinstellungenTest. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks
Warning: Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function. For more information, see https://reactjs.org/link/rules-of-hooks
Uncaught Error: Rendered more hooks than during the previous render.
The above error occurred in the <ComponentTest> component:

Now, I could just write

return <button onClick={() => setComponent(<SomeFunctionalComponent/>)}>Crash</button>

instead, but I think that creates the component too early. I want to create the component during the render, like this:

function ComponentTest() {
    const [component, setComponent] = useState<ReactNode | null>(null);


    return <component/>
}

I hope someone can help me out with this.

CodePudding user response:

You could hold the value of what component you want to use in the state and then use conditional rendering to render the one you want.

Something like this

function ComponentTest() {
  const [componentId, setComponentId] = useState<string | null>(null);


    return <button onClick={() => setComponent("myId")}> {componentId === "myId" && < SomeFunctionalComponent  /> }</button>
}

  • Related