26

I'm trying to learn reactjs and i have some uncertainties. I was refering react DOCS and some other tutorials and i saw functions are written inside render function and also inside class. What things should we do inside render function in react?

1st way

class App extends Component {

    test(user) {

        return user.firstName;
    }

    render() {

        const user = {
            firstName: 'Harper',
            lastName: 'Perez'
        };

        return (

            <div>

                <h1>{this.test(user)}</h1>

            </div>
        )
    }
}

2nd way

class App extends Component {

       render() {

        const user = {
            firstName: 'Harper',
            lastName: 'Perez'
        };

        function test(user) {

            return user.firstName;
        }

        return (

            <div>

                <h1>{test(user)}</h1>

            </div>

        )

    }
}

Both this methods work. But i want to know what is the best method to do this? Most importantly i want to know what kind of things i can do inside render function.

Thanks.

CraZyDroiD
  • 6,622
  • 30
  • 95
  • 182

2 Answers2

17

The render method normally gets called a lot of times. I think it is more performant to declare your functions outside of the render method if you can. See this answer for a more detailed explanation of the render method.

The test function in your example is a pure function, this allows you to declare it outside the scope/context of the react component altogether as it only needs access to the arguments that are passed in.

That said, it's perfectly fine to declare functions inside a render method or more commonly these days a functional component. There are hooks like useCallback that can help with performance but 99% of the time it's not an issue. Always remember that premature performance optimisation is the roof of all evil and you need to measure performance before you can improve it.

// helpers.js
const test = function(user) {
    return user.firstName;
}

// App.js
const App = () => {
  const user = {
    firstName: 'Harper',
    lastName: 'Perez'
  }

  return (
    <div>
      <h1>hello {test(user)}</h1>
    </div>
  )
}
spirift
  • 2,994
  • 1
  • 13
  • 18
  • 1
    Their is no point in declaring outside the class here. You can just attach the function to the class instead so you don't have to pass params in. The only reason to do this is if you are using a pure function. – Martin Dawson Mar 07 '17 at 11:35
  • 1
    @MartinMazzaDawson As I mentioned in my answer, because the OP is using a pure function this can be placed outside the context of the class which is more reusable and a better separation of concerns. – spirift Mar 07 '17 at 12:16
  • Could you clarify, what specifically about the example being a pure function enables it to be placed outside of the context of the class? Asked another way, what would be an example when the function could not be placed outside of the context of the class? – BenjiFB Jan 12 '21 at 14:37
  • You can place an impure function outside of the component and it will probably work perfectly well. The reason to declare inside a component is to more easily make use of internal props and hooks. If we're talking classes, you would have methods of a class to allow their use later and also to give access to private variables within the class. – spirift Jan 13 '21 at 10:18
14

I think it's ultimately your choice, but I personally prefer only putting functions within render that deal exclusively with rendering components and/or JSX (i.e. mapping over a prop, switch statements that conditionally load a proper component based on a prop, etc...). If the logic behind the function is heavy, I'll leave it out of render.

Here's an example. Say in your component you have a "users" prop that is supposed to display a list of users. You might have a render function with these types of things:

render(){
  
  // An array of user objects & a status string.
  const { users, status } = this.props;
  
  // Map users array to render your children:
  const renderUserList = () => {
    return users.map(user => {
      return <div>{ user.firstName }</div>;
    });
  };
  
  // Conditionally load a component:
  const renderStatus = () => {
    let component = '';
    switch(status){
      case 'loading':
        component = <Component1 />
        break;
      case 'error':
        component = <Component2 />
        break;
      case 'success':
        component = <Component3 />
        break;
      default:
        break;
    }
    
    return component;
  }
  
  // render() return:
  return(
    <div>
      <div className="status">
        { renderStatus() }
      </div>
      <div className="user-list">
        { renderUserList() }
      </div>
    </div>
  );
}

However, if you had a function that needed to somehow manipulate data about a user, it might be better to put that in a function outside of render.

Nate Kimball
  • 928
  • 8
  • 22