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>