---
# System prepended metadata

title: React | State
tags: [ironhack, ' lecture']

---

---
tags: ironhack, lecture, 
---

<style>
.markdown-body img[src$=".png"] {background-color:transparent;}

.alert-info.lecture,
.alert-success.lecture,
.alert-warning.lecture,
.alert-danger.lecture {
  box-shadow:0 0 0 .5em rgba(64, 96, 85, 0.4); margin-top:20px;margin-bottom:20px;
  position:relative;
  ddisplay:none;
  
}

.alert-info.lecture:before,
.alert-success.lecture:before,
.alert-warning.lecture:before,
.alert-danger.lecture:before {
  content:"👨‍🏫\A"; white-space:pre-line;
  display:block;margin-bottom:.5em;
  /*position:absolute; right:0; top:0;
  margin:3px;margin-right:7px;*/
}

b {
  --color:yellow;
  font-weight:500;
  background:var(--color); box-shadow:0 0 0 .35em var(--color),0 0 0 .35em;
}

.skip {
  opacity:.4;
}
</style>

![logo_ironhack_blue 7](https://user-images.githubusercontent.com/23629340/40541063-a07a0a8a-601a-11e8-91b5-2f13e4e6b441.png)

# React | State

## Learning Goals

* Learn what state is in a React component
* Learn the syntax of defining, modifying and using state

## Introduction

:::info lecture
props OK, recap :
- moyen de passer des paramètres depuis l'extérieur (lors de l'instantiation du composant)
- pouvant servir à l'affichage
- synchro avec le rendu DOM dans le temps
:::

In the previous lesson, we saw how props are important to the displaying of components. Now let's see what state is and why it's so important for us.

## State

:::info lecture
Les `state` sont une autre façon d'enregistrer des informations :
- mais cette fois, internes au composant (parallèle avec ses émotions)
- pouvant servir à l'affichage
- toujours synchro avec le DOM dans le temps
:::

One of the extra features that React `Component` classes have is **state**. State represents information that a component is in charge of managing that can **affect what the component diplays**. This information changes over time, which causes changes in the DOM.

React has a <b>built-in method for changing a component's state</b>. When you call it, React figures out what in the DOM needs to change and makes those changes automatically. If you do it right, changing the information in the state should **automatically update the DOM**.

:::info lecture
Dès qu'une prop ou state change, un re-rendu opère => engendrant *éventuellement* une mise à jour du DOM
:::

:::info
The <b>changes in `props` and/ or `state` trigger React to re-render the components and potentially update the DOM</b>.
:::

**So what kind of information should be saved in state?** Anything that will affect what users see and experience on the site.

:::info lecture
Exemples de state :
:::

- **Logged in?** - Whether or not we are logged-in has a big affect on what the user sees in an app.
- **User's details** - User details such as name, email and avatar changes the content of your app slightly.
- **Lists of data** - Lists of data such as videos on YouTube, products on Amazon, or notifications on Facebook are retrieved from the database and stored as state in a React app. We will store these in arrays so the amount is also part of the state.
- **Open or closed?** - The open/closed status of menus and popups in the app should also be stored as state. As the user interacts with the app, the different statuses are going to change.
- **Form data** - As users fill in forms in a React app, our code is going to be storing the information they typed in state. This will also allow us to pre-fill the form's inputs for things like edit forms.

Some of this may sound familiar to you because it's similar to the way hbs files use data that we send it from out routes. React components sometimes **feel like hbs files** in the sense that they are templates for displaying props and state data. The big difference here is that React components, props, and state **exist in the front end code on the browser**. Templates like hbs files are not visible to users. The browser just receives the already created HTML.


## State vs. Props

<b>State is similar to props</b> in that both state and props are used in the component's rendered JSX. The main difference is that state is **defined directly inside the component**. You see its initial value in the component and the changes to the values as well. However, props are sent to the component, which means we don't see the exact value of the props – only their names.

Also important to note is that the component that defines a piece of <b>state **is the only one that can change it**</b>. It's the component's responsibility to define its state and update it at the appropriate time based on user interaction. This is very different props because <b>a component **cannot change the values of the props** it receives</b>. Props are read-only.

As a reminder, **state** is only usable in your component classes that extend React's `Component`, whereas props can be used in both class components as well as functional ones.


## Adding state to a component
Similarly like we had in our *Props* lesson, here we will create *User* component and pass some data to it using *props*. In this case, our data will "live" in the state of *App* class, which will render *User* component.

Let's go to our `App.js`, the primary class component that extends React `Component` class, and let's introduce state there. First observe that **state is defined as an object**. Each key in the object is one piece of the state we are keeping track of in the component.

:::info lecture
- L5-L18: `state =` dans la classe
- `this.state` au sein des méthodes
:::

```jsx=
// src/App.js

class App extends Component {
  // 👇
  state = {
    userA: {
      firstName: "Harper",
      lastName: "Perez",
      avatarUrl:
        "https://www.refreshmiami.com/wp-content/uploads/2018/07/55085_logo-ironhack.png"
    },
    userB: {
      firstName: "Ana",
      lastName: "Hello",
      avatarUrl:
        "https://s3.amazonaws.com/owler-image/logo/ironhack_owler_20180828_221413_original.png"
    }
  };

  render() {
    // ...
    return (
      <div className="App">
        {/*              👇 */}
        <User firstName={this.state.userA.firstName} />
        <User firstName={this.state.userB.firstName} />

        {/* ... */}
      </div>
    );
  }
}

export default App;
```

Here we passed some data do the *User* component, but we still didn't create component itself. (After creating component, don't forget you have to import it to the App.js).
Let's create *User* component:

```jsx
// User.js
import React from "react";

class User extends React.Component {
  render() {
    return (
      <div class="User">
        <h2>Hello, {this.props.firstName}!</h2>
      </div>
    ); 
  }
}

export default User;
```

To change the state, some kind of event needs to be triggered. Generally speaking, changes to the state occur when the user interacts with the app.

Let's create `button` element in our `render()` method inside `App.js` and let's attach **onClick** listener to it. Also let's add two new properties inside our state object: `clickCount` and let's set it to `0` and `backColor` set to `yellow`. So at first we want to change the state of our App component and we want to see the changes reflecting on the DOM as we change the state. Let's create `clickHandler()` method that will update the state with every click on the button that has this event attached to it using *onClick* listener.

And our updated `App.js` now looks like this:

:::info lecture
Le changement de valeur d'un state sera généralement déclenché par une interaction utilisateur, comme l'appui sur un bouton. Définisson une méthode `clickHandler` qui sera appelée au click sur un bouton
:::

```jsx=
class App extends Component {
  state = {
    userA: {
      firstName: "Harper",
      lastName: "Perez",
      avatarUrl:
        "https://www.refreshmiami.com/wp-content/uploads/2018/07/55085_logo-ironhack.png"
    },
    userB: {
      firstName: "Ana",
      lastName: "Hello",
      avatarUrl:
        "https://s3.amazonaws.com/owler-image/logo/ironhack_owler_20180828_221413_original.png"
    },
    clickCount: 0 // 👈
  };

  // 👇
  clickHandler = () => {
    this.setState({
      clickCount: this.state.clickCount + 1 // increment
    });
  };

  render() {
    return (
      <div className="App">
        <h1> Hello Ironhackers! </h1>
        
        {/* 👇 */}
        <p>Count is: {this.state.clickCount}</p>
        <button onClick={this.clickHandler}>Click me</button>

        <User firstName={this.state.userA.firstName} />
        <User firstName={this.state.userB.firstName} />
      </div>
    );
  }
}
```

:::info lecture
- L15: ajout d'un state `clickcount`
- L32: ajout d'un bouton dans l'UI avec attribut `onClick`
- L19-L23: ajout d'une méthode `clickHandler` répondant au click
- L20-L22: `this.setState()`

:::

<div class="skip">

Now we can add other properties to our users:

```jsx
// User.js
import React from "react";

function User(props) {
  return (
    <div>
      <h2 style={{ backgroundColor: props.theColor }}>
        Hello, {props.firstName} {props.lastName}!
      </h2>
      <img src={props.image} width="370" height="300" />
    </div>
  );
}

export default User;
``` 

Note that we used predefined method **setState()** to update the state. This method is one of Component's built-in methods and it's mandatory to use it when updating the state. **It's wrong to directly assign changes to the state object**. Always use the `setState()` method for updating state. If you don't use the method, the DOM won't be updated.

The last thing we want to cover is how to make the changes in state reflect visually in the DOM. So let's say we want to update `backgroundColor` property of the *h2* tag inside `User.js` component on every click, but when `clickCount` is 5 we want to change names of our users and we want to set the background to original color *yellow*.

This means we will have to update the state of `App.js` conditionally and these updates will trigger changes in `User.js` component through the props that are passed. Make sure you add `colorMapper()` method, which will help us to change background color to the random colors.

</div>

<div class="skip">

Let's update `App.js` one more time:

```jsx
// App.js - add changes to clickHandler(), add new colorMapper() method, the rest of the code stays the same
// ...
  colorMapper = () => {
    return "#" + Math.floor(Math.random() * 16777215).toString(16);
  };

  clickHandler = () => {
    const newCount = this.state.clickCount + 1;

    if (newCount !== 5) {
      this.setState({
        clickCount: newCount,
        backColor: this.colorMapper()
      });
    } else {
      this.setState({
        clickCount: newCount,
        backColor: "yellow",
        userA: {
          firstName: "Jon",
          lastName: "Doe",
          avatarUrl:
            "https://www.refreshmiami.com/wp-content/uploads/2018/07/55085_logo-ironhack.png"
        },
        userB: {
          firstName: "Susanne",
          lastName: "Smith",
          avatarUrl:
            "https://s3.amazonaws.com/owler-image/logo/ironhack_owler_20180828_221413_original.png"
        }
      });
    }
  };
// ...
```

</div>

## Summary

In this learning unit we covered another essential concept in the React – referring to changes within the component using *state*. State and props differ in these main ways:

1. State is defined in the component while props are sent to the component so we don't see their values.
2. State can be changed by the component while props are read-only.
3. State can be used only in class components while props can be used in class and functional components.

## Extra Resources

- [Understanding the Fundamentals of State in React](https://medium.com/the-andela-way/understanding-the-fundamentals-of-state-in-react-79c711be677f)
- [`SyntheticEvent` on reactjs.org](https://reactjs.org/docs/events.html)