Search code examples
reactjsrendering

ReactJS Functional Component vs Component Functions for conditional rendering


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?


Solution

  • 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.