State Management in React
Tags: javascript, react, webdev
Published: 2020-07-11 16:39:52

Hello Developers! 
In this post, we are going to learn State Management in React JS.

### **What is State??**
Every React component returns JSX which describes what the UI should look like. The `state` is a reserved word in React. So the state is an object that represents the parts of the app that can change. 

As of React `v16.8` Hooks are introduced which let you use state and other React features in functional components.

### **Setting up our Project**
Firstly, let's create a React app with [create-react-app](https://github.com/facebook/create-react-app).  Create React App is an officially recommended tool for building react apps. You’ll need to have `Node >= 8.10 and npm >=5.6` on your machine. To create and run the project type the following commands:

```
npx create-react-app my-app
cd my-app
npm start
```

In this tutorial, we will be building a  simple counter app in which you can increment or decrement the count.

<img src="https://media.giphy.com/media/Su0KBvCYddcIzIFPdf/giphy.gif" />

_**Now let's jump into the Code!**_ 
<br>
Let's create the basic structure for our counter app.
_**src/App.js**_

```Javascript
import React, { Component } from "react";
import "./App.css";

class App extends Component {
    onIncrementHandler = () => {

    };

    onDecrementHandler = () => {

    };

    render() {
        return (
            <div className="App">
                <h3 className="counter">0</h3>
                <div className="container">
                    <button onClick={this.onIncrementHandler}>Increment</button>
                    <button onClick={this.onDecrementHandler}>Decrement</button>
                </div>
            </div>
        );
    }
}

export default App;

```
<br>
We are in App.css, let’s add some styles for our counter app so that it looks better:
_**src/App.css**_

```CSS
.App {
    height: 100vh;
    overflow: hidden;
    text-align: center;
    display: flex;
    flex-direction: column;
}

.counter{
    font-size: 150px;
    font-weight: 400;
}
.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

button {
  width: 15%;
  margin: 0 30px;
  font-size: 30px;
  color: white;
  background-color: black;
  border: none;
  transition: transform .2s;
  cursor: pointer;
}

button:hover {
  border: 1px solid black;
  color: black;
  background-color: white;
  transform: scale(1.2);
}

```

You must have observed that we have hard-coded the value of the counter to 0. So, how to manipulate the counters value🤔??

To manipulate the value of the counter we introduce state. A state is a javascript object where you store property values that belongs to the component. When the state of components changes, so does the component UI.

**Adding Local State to a Class**

```Javascript
state = {
    counter: 0
}
```

To get the counter dynamically replace `<h3 className="counter">0</h3>` with

```HTML
<h3 className="counter">{this.state.counter}</h3>
```

**Using State Correctly**

`setState()` is the legitimate way to update state after the initial state setup.

```Javascript
// Right
this.setState({comment: 'Hello World!'});
```

Here, we’re passing an object to `setState()`. The object contains the part of the state we want to update which, in this case, is the value of comment. React takes this value and merges it into the object that needs it.

Do not modify state directly. We should always update state immutably. 

```Javascript
// Wrong
this.state.comment = 'Hello World';
```

If you have to use the previous state for updation the above method won't work. So, the alternative for the above approach is:

```Javascript
this.setState((prevState) => {
    counter: prevState.counter + 1
});
```

Now lets update our state in `onIncrementHandler` and `onDecrementHandler`.

```Javascript
onIncrementHandler = () => {
        this.setState((prevState) => ({
            counter: prevState.counter + 1,
        }));
};

onDecrementHandler = () => {
        this.setState((prevState) => ({
            counter: prevState.counter - 1,
        }));
};
```

Final updated code with state management looks like:

```Javascript
import React, { Component } from "react";
import "./App.css";

class App extends Component {
    state = {
        counter: 0,
    };

    onIncrementHandler = () => {
        this.setState((state) => ({
            counter: state.counter + 1,
        }));
    };

    onDecrementHandler = () => {
        this.setState((prevState) => ({
            counter: prevState.counter - 1,
        }));
    };

    render() {
        return (
            <div className="App">
                <h3 className="counter">{this.state.counter}</h3>
                <div className="container">
                    <button onClick={this.onIncrementHandler}>Increment</button>
                    <button onClick={this.onDecrementHandler}>Decrement</button>
                </div>
            </div>
        );
    }
}

export default App;

```