All the other answers are working fine but I would add some extra, because by doing this:
- It is a bit safer. Even if your type-checking is failing you still
return a proper component.
- It is more declarative. Anybody by looking at this component can see what it could return.
- Its is more flexible for example instead of 'h1', 'h2', ... for type of your Heading you can have some other abstract concepts 'sm', 'lg' or 'primary', 'secondary'
The Heading component:
import React from 'react';
const elements = {
h1: 'h1',
h2: 'h2',
h3: 'h3',
h4: 'h4',
h5: 'h5',
h6: 'h6',
};
function Heading({ type, children, ...props }) {
return React.createElement(
elements[type] || elements.h1,
props,
children
);
}
Heading.defaultProps = {
type: 'h1',
};
export default Heading;
Which you can use it like
<Heading type="h1">Some Heading</Heading>
or you can have a different abstract concept, for example you can define a size props like:
import React from 'react';
const elements = {
xl: 'h1',
lg: 'h2',
rg: 'h3',
sm: 'h4',
xs: 'h5',
xxs: 'h6',
};
function Heading({ size, children }) {
return React.createElement(
elements[size] || elements.rg,
props,
children
);
}
Heading.defaultProps = {
size: 'rg',
};
export default Heading;
Which you can use it like
<Heading size="sm">Some Heading</Heading>