useState Hook
Tags: react, webdev
Published: 2021-01-09 04:53:31

## What are React Hooks?
React Hooks are built-in functions that allow us to use state and lifecycle methods in functional components.

---

## Rules of Hooks
- Starts with `use`
- Always should be invoked inside a function/component body or in another hook
- The component in which it's being used should be uppercase (custom component)
- Don’t call Hooks inside loops, conditions, or nested functions

---

## useState Basics
`useState` enables us to add state to functional components.
It takes in a value (initial state) that can be anything (array, object, string, boolean, etc) and returns an array consisting of the current state and a function that updates the state.
> One important thing to remember is the update function doesn't update the state right away.

``` js
import React, { useState } from "react";

const App = () => {
  const [value, setValue] = useState(0);
  return (
    <div className="App">
      <h1>Counter: {value}</h1>
      <button>Increment</button>
    </div>
  );
};
export default App;
```

---

### Updating the state
- Let's update the counter whenever we click on a button
```js
import React, { useState } from "react";

const App = () => {
  const [value, setValue] = useState(0)
  return (
    <div className="App">
      <h1>Counter: {value}</h1>
      <button onClick={(() => setValue(value + 1))}>
        Increment
      </button>
    </div>
  );
}
export default App;
```
---

### Delaying the increment for a while after click
```js
import React, { useState } from "react";

const App = () => {
  const [value, setValue] = useState(0)

  const complexIncrease = () => {
    setTimeout(() => {
      setValue(value + 1)
    }, 2000)
  }
  return (
    <div className="App">
      <h1>Counter: {value}</h1>
      <button onClick={(() => setValue(value + 1))}>
        Increment
      </button>
      <button onClick={complexIncrease}>
        Complex Increase
      </button>
    </div>
  );
}
export default App;
```
- There's a gotcha above. If you continuously click on complex increment, you may notice that the value changes only once, no matter how many times you clicked.
- To fix this, use Functional update of useState:

---

### Functional Update (useState)
```js
useState((previousstate) ⇒ {

// Always return something
// change previous state

return new state

})
```
- If the new state is computed using the previous state, we can pass a function to useState. The function will receive the previous value, and return an updated value

```js
import React, { useState } from "react";

const App = () => {
  const [value, setValue] = useState(0)

  const complexIncrease = () => {
    setTimeout(() => {
      setValue((prev) => prev + 1)
    }, 2000)
  }
  return (
    <div className="App">
      <h1>Counter: {value}</h1>
      <button onClick={(() => setValue(value + 1))}>
        Increment
      </button>
      <button onClick={complexIncrease}>
        Complex Increase
      </button>
    </div>
  );
}
export default App;
```
- Now the counter works perfectly. 🤟🏻

---
Here's the [sandbox](https://codesandbox.io/s/fast-snow-1dm22?file=/src/App.js) link for above code.