1

I want to dynamically create a component, when I implement something like this:

const gen_Comp = (my_spec) => (props) => {
    return <h1>{my_spec} {props.txt}</h1>;
}

const App = () => {
    const Comp = gen_Comp("Hello");
    return (
        <Comp txt="World" />
    );
}

Something goes wrong (what exactly goes wrong is hard to explain because it's specific to my app, point is that I must be doing something wrong, because I seem to be losing state as my component gets rerendered). I also tried this with React.createElement, but the problem remains.

So, what is the proper way to create components at runtime?

1
  • what do exactly mean to generate dynamic component? Do you want to pass props and then want to render that in separate common component? Commented Oct 22, 2021 at 12:58

1 Answer 1

2

The main way that react tells whether it needs to mount/unmount components is by the component type (the second way is keys). Every time App renders, you call gen_Comp and create a new type of component. It may have the same functionality as the previous one, but it's a new component and so react is forced to unmount the instance of the old component type and mount one of the new type.

You need to create your component types just once. If you can, i recommend you use your factory outside of rendering, so it runs just when the module loads:

const gen_Comp = (my_spec) => (props) => {
    return <h1>{my_spec} {props.txt}</h1>;
}
const Comp = gen_Comp("Hello");

const App = () => {
    return (
        <Comp txt="World" />
    );
}

If it absolutely needs to be done inside the rendering of a component (say, it depends on props), then you will need to memoize it:

const gen_Comp = (my_spec) => (props) => {
    return <h1>{my_spec} {props.txt}</h1>;
}

const App = ({ spec }) => {
    const Comp = useMemo(() => {
      return gen_Comp(spec);
    }, [spec]);
    return (
        <Comp txt="World" />
    );
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.