Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between using a stateless functional component versus calling a method?

I'm trying to understand stateless components and what the difference is between these examples:

class App {
  render() {
    return (
      <div>
        {this.renderAFunction('hello')}
      </div>
    );
  }
  renderAFunction(text) {
    return (
      <p>{text}</p>
    );
  }
}

and this:

class App {
  render() {
    return(
      <div>
        <RenderAFunction text='hello'/>
      </div>
    );
  }
}

const RenderAFunction = ({text}) => (
    <p>{text}</p>
);

Or if there is any difference at all?

like image 762
groovy Avatar asked Feb 03 '16 22:02

groovy


2 Answers

Functionally, there is absolutely no difference. Both end up rendering a paragraph element, but there are other aspects to consider. There are three points to make (in my opinion) when examining both methods:

  • Reusability: You have to understand to separate components when you need to. If renderAFunction is just meant to generate some JSX based on, for example, an API request, then it's fine being in a method. But if you want to reuse it somewhere else, then separate it into it's own component. A huge part of React is component reusability and getting rid of code duplication. Separating the method into it's own component would be imperative to accomplish this.
  • Purpose: There are reason to use stateless function components and reasons not to. The whole point of stateless functional components is to not have state and be presentational. If you need to do something that involves the React lifecycle or internal state, keep it as a method, or new class depending on if you want it reusable.
  • Performance: Using a stateless functional component would be less efficient. This is because it's a component, not just some JSX returned from a method. As of right now, the React team plans on making some optimizations for stateless functional components because they do not contain state and are merely presentational, but this probably won't happen until after React Fiber is done and thus your stateless functional component has no optimizations versus a regular full-fledged class component. That makes it incredibly inefficient versus a method returning some JSX, especially if it's just used once in another component.

A good rule of thumb is to ask yourself, do I need it anywhere else? If not, then keep it in a method. If you don't need it anywhere else, separating the JSX into a separate component would have worse performance and wouldn't follow React's core principles.

If you are going to need it somewhere else, then separate the component so you follow React's concept of reusability.

like image 140
Andrew Li Avatar answered Nov 14 '22 22:11

Andrew Li


Your App's render function will be translated into following JS code for your first example:

render() {
   return React.createElement(
     'div',
     null,
     this.renderAFunction('hello')
   );
 }

And the following one for the second one:

render() {
  return React.createElement(
    'div',
    null,
    React.createElement(RenderAFunction, { text: 'hello' })
  );
}

While they both looks almost the same, there is one significant difference: laziness. React will execute RenderAFunction body only in case it gonna be mounted to the DOM hierarchy.

It is insignificant is your case, but imaging following example:

const LazyApp = () => {
  const heavy = <div><HeavyStuff /></div>
  // ...
  return <div>done it</div>
}

const HardWorkingApp = () => {
  const heavy = <div>{HeavyStuff()}</div>
  // ...
  return <div>done it</div>
}

const HeavyStuff = () => {
  // ... do heavy rendering here
}

Lazy app will not perform any heavy stuff at all. Maybe it is not very clear from that synthetic example why one would do anything like that at all. But there are real-world examples out there, when something conceptually similar (creating Components without rendering them) is happening.

like image 22
fkulikov Avatar answered Nov 14 '22 23:11

fkulikov