32

Is there a preference on where you put functions inside a react component? I am still learning React so just trying to figure out the best practices.

class Content extends React.Component {
  // What is the difference between putting functions here such as 
  Hello() {

  }
  
  render() {
    // or here
    Hello() {

    }

    return() (
      <div>blah blah</div>
    );
  }
}
Saeed Zhiany
  • 2,051
  • 9
  • 30
  • 41
Whymess
  • 697
  • 3
  • 8
  • 20

2 Answers2

52

A function in the render method will be created each render which is a slight performance hit. It's also messy if you put them in the render, which is a much bigger reason, you shouldn't have to scroll through code in render to see the html output. Always put them on the class instead.

For stateless components, it's probably best to keep functions outside of the main function and pass in props instead, otherwise the function will be created each render too. I haven't tested performance so I don't know if this is a micro-optimization but it's worth noting.

Example:

const MyStatelessComponent = ({randomProp}) => (
    render() {
        doSomething(randomProp);

        return <div />
    }
);

doSomething = (randomProp) => {
    //Do something here
}
Martin Dawson
  • 7,455
  • 6
  • 49
  • 92
  • i did same way on my projects – yussan Mar 30 '17 at 07:19
  • if you made doSomething a component like const DoSomething = (props) => { ...} and then in the render used it like I think this might mitigate the performance hit according to the docs https://reactjs.org/docs/conditional-rendering.html – taylor michels Feb 03 '22 at 19:17
6

It's worth pointing out that there are times when you want to perform intensive calculations in the render() and take the performance hit. Especially when it involves making calculations from props. Take the case of

class Person extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      name: props.firstName + props.lastName,
    };
  }

  render() {
    return <div> {this.state.name} </div>;
  }
}

Now when props changes, the state won't be updated as the constructor function only runs when the component is mounted. A better way would be to make the calculation in render. So whenever your component rerenders, it recalculates and renders the right value.

class Person extends React.Component {
  render() {
    const myName = this.props.firstName + this.props.lastName;

    return <div> {myName} </div>;
  }
}

And this version is a bit cleaner to read:

class Person extends React.Component {
  calculateName = () => {
    return this.props.firstName + this.props.lastName;
  }

  render() {
    const myName = this.calculateName();

    return <div> {myName} </div>;
  }
}
Gunther
  • 561
  • 8
  • 12
  • 1
    Wouldn't another way of doing this be to use the componentWillRecieveProps() method to update state? – Andrew Aug 10 '18 at 16:53
  • 1
    Somewhat. Cwrp is 1. deprecated in react 16+ and 2. cwrp does not get triggered on initial render. Running the calculation in the render ensure it runs on render. – Gunther Aug 10 '18 at 22:09