2

What is the better way to pass a component in props? And how it's better to call it as Component or as a function. Or there are no differences?

const HeaderComponet = props => {
  return <div style={styles.header}>Header</div>;
};

const renderCardBody = props => {
  return <div style={styles.body}>Body</div>;
};

function App() {
  return (
    <Card HeaderComponet={HeaderComponet} renderCardBody={renderCardBody} />
  );
}
const Card = props => {
  const { HeaderComponet, renderCardBody } = props;
  return (
    <div>
      <p>Card</p>
      {HeaderComponet && <HeaderComponet {...props} />}
      {renderCardBody && renderCardBody(props)}
    </div>
  );
};

codesandbox https://codesandbox.io/s/hungry-violet-jlvsp

2 Answers2

3

I would simply render it as Child Component

<Card>
  <HeaderComponent {...props}/>
  <RenderCardBody {...props}/>
</Card>
adiga
  • 34,372
  • 9
  • 61
  • 83
Shankar Regmi
  • 854
  • 1
  • 7
  • 16
2

how it's better to call it as Component or as a function

In theory, both are same. JSX we write is converted to a function based JS and is used in that way.

Sample:

So which to use?

  • Function: If there is a processing involved. Say based on 1 state, it should show banner. On another, a form. Yes, the logic can be moved to another component as used, however, if a component needs to be smart and do processing based on state, such processing should be done in a function
  • Component: If its directly consumed. Like an form component wrapping multiple component to create a structure.

What is the better way to pass a component in props?

In my POV, you should not pass components as props. A component should know what its consuming. Still if you want to have dynamic component, I'd do in following manner.

  • Create a list of possible components that can be used and based on that create a map.
  • Create props getter function so you can dynamically use it.
  • Now based on props, get the component and props, and do rendering.

Sample:

What is the better way to pass a component in props?

Note: The Tile components are just for demo and hence they are very basic. In reality, they can be more complicated

const DefaultTile = (props) => Array.from({ length: props.count }, (_, i) => <div className='tile medium-tile' key={i}>Tile</div>) 

const LargeTile = (props) => Array.from({ length: props.count }, (_, i) => <div className='tile large-tile' key={i}>Tile</div>) 

const SmallTile = (props) => Array.from({ length: props.count }, (_, i) => <div className='tile small-tile' key={i}>Tile</div>) 

const componentMap = {
  large: LargeTile,
  medium: DefaultTile,
  small: SmallTile
}
  
const renderPropMap = {
  large: (props) => ({ count: props.count, showExtraInfo: props.info }),
  medium: (props) => ({ count: props.count }),
  small: (props) => ({ count: props.count, onHover: props.onHover })
}  

const App = (props) => {
  const Comp = componentMap[props.size];
  const childProps = renderPropMap[props.size](props)
  return <Comp { ...childProps } />
}

ReactDOM.render(<App size='medium' />, document.querySelector("#app"))
.tile {
  border: 1px solid gray;
  display: inline-block;
  margin: 4px;
}

.small-tile {
  width: 50px;
  height: 50px;
}

.medium-tile {
  width: 100px;
  height: 100px;
}

.large-tile {
  width: 200px;
  height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="app"></div>
Community
  • 1
  • 1
Rajesh
  • 24,354
  • 5
  • 48
  • 79