2

I am fairly new to react and this is a problem I am trying to solve.

There is a parent component parent which passes props to the child. One of these props, include an element to be rendered like this:

<child componentToBeRendered = {component} />

In the child, I want to take this component and pass a prop to it, which is defined in the child itself.

function child(props){
    function toBePassed(){ ... }
    <props.componentToBeRendered fun = {toBePassed} />
}

I know that the above code is wrong and we cannot use <props.componentToBeRendered>. So how can I pass a custom prop to this component?

The only way I can think of rendering the component is like: {props.componentToBeRendered};

How do I render this component with a custom prop defined in the child?

Giridhar
  • 155
  • 1
  • 8

3 Answers3

2

You can rename the passed component prop, render it as per usual, and pass props to it as per usual. Similar to Choosing the Type as Runtime

function Child(props){
    const ComponentToBeRendered = props.componentToBeRendered;

    function toBePassed(){ ... }

    return <ComponentToBeRendered fun={toBePassed} />;
}

I've usually used this pattern with prop destructuring in the function signature, renaming the destructured prop.

function Child({ componentToBeRendered: ComponentToBeRendered }) {
  function toBePassed(){ ... }

  return <ComponentToBeRendered fun={toBePassed} />;
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
1

You can use React's top-level API, specifically React.createElement, for instance:

const MyChild1 = ({ num }) => <div>num1: {num}</div>;
const Parent = ({ comp }) => 
  <div>
    {React.createElement(comp, { num: 5 })}
    {React.createElement(comp, { num: 1 })}
  </div>
;
MorKadosh
  • 5,846
  • 3
  • 25
  • 37
-1

I think you shouldn't pass the component as a prop Instead pass a value to the child that indicates the component to be rendered.

function Parent(){
   return <Child toBeRendered="contact"/>
}
function Child(props){
   let toBeRenderd;
   switch(props.toBeRendered){
      case 'contact' :
          toBeRendered = Contact;
      default :
          toBeRendered = Info
   }
   return <toBeRendered/>
}
  • `toBeRendered` isn't a valid react component name. This approach is ok if the set of components is small and manageable, but doesn't cover well if *any* component is allowed to be passed and rendered (think an arbitrary set of icon components where there could be hundreds). This won't scale well at all. – Drew Reese Sep 03 '20 at 06:14