Sometimes I want to move my conditional rendering out of render()
, and I always have dilemma between these two approaches:
class MyComponent extends React.Component {
_renderSomething() => {
const {x, y, z} = this.props
// conditional rendering based on props
}
render() {
return (
{ this._renderSomething }
// vs
{ renderSomething(this.props) }
// which one is better?
)
}
}
const renderSomething = (props) => {
const {x, y, z} = props
// conditional rendering based on props
}
export default MyComponent
Any performance difference between _renderSomething
and this.renderSomething
?
When should I use which?
There is a performance penalty with Functional Components vs Functions returning elements. An example would be this -
// Component approach
let Tab = ({label, link}) => <li><a href={link}>{label}</a></li>;
class Tabs extends Component {
render(){
return (
// notice the key prop is handled by parent render
<ul>{this.props.tabs.map(tab => <Tab {...tab} key={link}>)}</ul>
)
}
}
// function based approach, notice the key prop is handled by the function
let tab = ({label, link}) => <li key={link}><a href={link}>{label}</a></li>;
class Tabs extends Component {
render(){
return (
<ul>{this.props.tabs.map(item => tab(item))}</ul>
)
}
}
In Component example, you will end up with unnecessary intermediate Tab
components, which will add to the virtual dom, however small they are. And then as they grow, these components will eventually cause slow renders. React will need to keep track of these components over subsequent renders. And these being functional components, you would not have access to shouldComponentUpdate
based optimizations.
The function version will not suffer from this as it returns Elements
directly, instead of components. Also, with smaller functions, there will be gains due to code inlining.
An extended discussion into this approach is here.