DEV Community

Cover image for React JS: Stateful vs Stateless Components
addupe
addupe

Posted on • Edited on

React JS: Stateful vs Stateless Components

Components are just the parts of our application in React JS. Each component needs to handle data, either to render it on the page or to pass it along to another component. The way that a component deals with data defines if that app is stateful or stateless.

Stateful components deal with data in 'state,' keeping a reference to a set of data that may change, while stateless components keep receive data in the form of props (short for properties) received from a parent component or a lineage of parent components, at least one of these parent components being stateful themselves.

Let's say we build a little web app to keep track of our personal reading list:

This small app would have a few small components. This one has three:

1) The main (stateful) app component which tracks all data and renders other child components:

class ReadingApp extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
        //these might change
        //add books, finish reading books
      books: this.props.books,
    };
Enter fullscreen mode Exit fullscreen mode

2) A stateless ReadingList component that contains a child component and passes the data received from the main ReadingApp along:

const ReadingList = (props) => {
  return (
    <table>
    <tbody>
      {books.map(book => {
        return <ReadingListEntry book={book} />
      })}   
    </tbody>
  </table>
  );
Enter fullscreen mode Exit fullscreen mode

3) This ReadingListEntry component, of which a new instance of is created each time another book is added to the state and which itself includes a toggling state changing click event:

class ReadingListEntry extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      showQuote: false,
    };
  }

render() {
    const { title, cover, quote } = this.props.book;
    return (
      <tr onClick={() => this.setState({ showQuote: !this.state.showQuote})}>
        <div className="book-title-container">
        <td className="book-title">{title}</td>
        </div>
        <td>
          <img src={cover}/>
        </td>
        {this.state.showQuote ? <td className="book-quote">{quote}</td> : null}
      </tr>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Notice that our two stateful components are written in the ES6 Class instantiation patterns. Stateful components are referred to as Class Components and are extended from React.Component, inheriting its stateful reactivity from the React library. Stateful components can also receive props though and in my examples, the state is defined with a value accessed from the passed down props.

Stateless components only receive props and are written as Function declarations. Stateless components are static and often act like containers in an application. They themselves do not need to have data re-rendered, but can pass along changing data.

The main ReadingApp component needs to be stateful to render books as they are added, deleted, or order swapped.

The ReadingList component can be stateless, because it's main responsiblity is acting as a container for the ReadingListEntry components it renders with its inherited data passed right along. ReadingListEntry again, is stateful, for the clicks. A showQuote property is set on the ReadingListEntry components' state object, which will be switched back and forth true/false on click and checked before displaying. Seen below:

In designing our components, it's important to only give state when necessary. If the component is passing data and not meant to be interactive, let it remain stateless. Give parents state over children, unless the child has its' own reason to have state (like in the case of our click function).

*In React 16.8, Hooks are introduced, which use a form of state without class instantiation. More on that in the docs: React Hooks

ursula k. le guin reading her translation of the tao te ching

Top comments (1)

Collapse
 
conermurphy profile image
Coner Murphy

My current process for deciding if an component needs to be stateful or stateless is to define it as a stateless component and then if the need for it to store data arrises, I then convert it into a stateful component. This way only the components that need state are given state.