Home > Back-end >  Render component by function pointer and pass props
Render component by function pointer and pass props

Time:10-30

I have an array of pointers, componentArray, but I'm struggling to figure out the syntax to both render them in ParentComponent



function Component1() {
    return(
        <h1>Hello from Component 1</h1>
    );
}

function Component2() {
    return(
        <h1>Hello from Component 2</h1>
    );
}

export const componentObject = [{
    name: "Component1",
    pointer: Component1
}, {
    name: "Component2",
    pointer: Component2
}];

function ParentComponent(props) {
    return (
        <div>
            {Object.entries(componentObject).map((ChildComponent) => (
                <span>{ChildComponent[1]() DOESNOTWORKPROP="Test"}</span>
            ))}
        </div>
      );
};

The above will work if you remove DOESNOTWKRPROP="TEST", but will not work when trying to add props to the children.

CodePudding user response:

Here you should not call directly ChildComponent as a function. You should use the "tag syntax", as follows:

function ParentComponent(props) {
    return (
        <div>
            {componentObject.map(({ pointer: ChildComponent }) => (
                <ChildComponent DOESWORKPROP="Test" />
            ))}
        </div>
      );
};

Note that the variable used in the tag should use PascalCase for react to accept it, thus the renaming as ChildComponent after destructuring pointer.

Here is the related documentation: https://reactjs.org/docs/jsx-in-depth.html#choosing-the-type-at-runtime

Bonus: you should provide a prop key to element generated with map. Here you can use the name of your components ;)

<ChildComponent key={ChildComponent.name} DOESWORKPROP="Test" />

Going further, when you call the function directly here:

<span>{ChildComponent[1]() DOESNOTWORKPROP="Test"}</span>

Your component is executed immediately and returns static JSX, as if your code became:

<span>{<h1 DOESNOTWORKPROP="Test">Hello from Component 1</h1>}</span>

That why your props don't apply: they are passed to a static JSX element, not to the dynamic rendering process of your component

CodePudding user response:

Since the componentObject is an array so you just need to use map().

And try this way:

function ParentComponent(props) {
    return (
        <div>
            {componentObject.map(({ pointer }) => {
                const ChildComponent = pointer;
                return <ChildComponent DOESNOTWORKPROP="Test" />
            })}
        </div>
      );
};
  • Related