Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: Are classes without state still considered stateless/pure?

I've been refactoring my app to make more components stateless/pure components; i.e., they're just functions. However, I noticed that some components will need to connect with the redux store via mapStateToProps. Which causes me to do something like this:

const someComp = (props) => {
  const {
    funcFromReduxStore,
  } = props;

  return (
    ...
    <SomeComponent
      func={ funcFromReduxStore(myArgs) }
    ...
  );
};

This will not work because I am executing funcFromReduxStore. An easy solution is to wrap the prop in an arrow function. However, this causes many unnecessary re-renders b/c the function won't be bound.

The question then becomes: How do I bind a function in a stateless component?

Is it still stateless if I make it a class, without a constructor, and create a class instance field as so:

class someComp extends React.Component {
  const {
    funcFromReduxStore,
  } = this.props,

  wrapper = (x) => funcFromReduxStore(x) // equivalent way to bind w/ ES8+

  render() {
    ...
    <SomeCompnent
      func={ wrapper(myArgs) }/>
    ...
  }
}

I don't have a constructor, nor state. I want to keep the comopnent stateless, but I also want to bind the function to avoid unncessary re-renders. I also want to continue to keep it stateless b/c React has stated there will be performance benefits for stateless comopnents. Does this qualify as a workaround?

like image 306
TheRealFakeNews Avatar asked Mar 01 '17 00:03

TheRealFakeNews


People also ask

Are pure components stateless?

In this take, we'll look at the following React component types: Class components (formerly 'Stateful' components) Pure components. Function components (formerly 'Stateless' components)

Is React stateless or stateful?

React Programming Pattern // This is a stateless child component.

Are class components stateless?

A stateless component renders output which depends upon props value, but a stateful component render depends upon the value of the state. A functional component is always a stateless component, but the class component can be stateless or stateful. There are many distinct names to stateful and stateless components.

Why stateless is better than stateful React?

Stateless components are simple functional component without having a local state but remember there is a hook in react to add state behavior in functional component as well. Stateful component can contains the state object and event handling function, user actions as well.


1 Answers

Short answer, no. Stateless functional components need to be simple functions.

You should take a look at the Recompose library for some really cool helpers that allow you to beef up your SFCs.

If you're trying to prevent unnecessary re-renders, you could look into onlyUpdateForKeys() or pure().

EDIT: So, I've been thinking about this a bit more and found this really great article on React component rendering performance. One of the key points in that article that pertains to your question:

Stateless components are internally wrapped in a class without any optimizations currently applied, according to Dan Abramov.

From a tweet in July 2016

So it appears that I was wrong. "Stateless Functional Components" are classes...for now. The confusing thing is that there have been performance improvements theorized:

In the future, we’ll also be able to make performance optimizations specific to these components by avoiding unnecessary checks and memory allocations.

At this point, I think the answer to your question becomes largely subjective. When you make a class that extends a React Component, any instances of your class get the setStateprototype method. Meaning you have the ability to set state. So does that mean it's stateful even if you're not using state? Thanks to @Jordan for the link to the code. SFCs only get a render method on the prototype when they are wrapped in a class by React.

To your point about wanting to bind functions, there's only two reasons I can think of that you'd want to bind the function:

  1. To give the function access to this (the instance of the component). From your example, it doesn't seem like you need that.
  2. To ensure that the function passed as a prop to a child component always retains the same identity. The wrapper function in your example seems unnecessary. The identity of the function is determined by the parent component (or mapStateToProps, or whatever HOC).

You should also take a look at React's PureComponent which does the same kind of shallow checking that the pure() HOC from recompose does.

like image 126
Bryan Downing Avatar answered Sep 22 '22 03:09

Bryan Downing