React Hooks - useState and useReducer cheat sheet - for developers who don't know Redux
Tags: react, javascript, tutorial, beginners
Published: 2020-10-11 23:54:44

I was having trouble to understand `useReducer` because I don't have Redux background. So I wrote this article to explain it to myself, and I hope it can help you as well.

#Learn `useState` first
If you know how `useState` works, then you can skip this section, and I am going to compare `useReducer` to `useState`.

###`useState` example ([reactjs.org](https://reactjs.org/docs/hooks-state.html))
```javascript

  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
```

`const [count, setCount] = useState(0);`

* `useState(0)`: It passes the initial state (in this case, it is 0), and returns an array with 2 elements - `count` and `setCount`. 
* `count`: new state
* `setCount`: the function that uses to change the state value. It is like `this.setState()` in class based component. 

#Compare to `useReducer`
`useReducer` is used for complicated `state` situation.
For example, I want to add one more button to decrease counter.

Here is the code by using `useState`
###`useState` example ([reactjs.org](https://reactjs.org/docs/hooks-state.html))

```javascript
 const [count, setCount] = useState(0);

  return (
    <div>
      {count}
      <button onClick={() => setCount(count + 1)}>
        +
      </button>
      <button onClick={() => setCount(count - 1)}>
        -
      </button>
    </div>
  );
}
```
We are going to move `count+1` and `count -1` to a `FUNCTION` by using `useReducer`

```javascript
const [count, setCount] = useReducer(FUNCTION, {count: 0})
```
In `useReducer`, we call `count` as `state`, `setCount` as `dispatch`, and `FUNCTION` is `reducer`

So it looks like this - 
```javascript
const [state, dispatch] = useReducer(reducer, {count: 0})
```
[MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) explains pretty well what is `Array.prototype.reduce()` is. It may help you to understand what is the reducer funciton in `useReducer`.

###Next, we are going to write the reducer function

`reducer function` passes 2 parameters

```javascript
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}
```

`state`: the current state
`action`: if I want to change state, then I call dispatch function. In this case, the first element is `type`, refer to `action.type`.

For example, I call `dispatch({type: 'increment'})`, then `count` will be + 1.

```javascript
<button onClick={() => dispatch({type: 'decrement'})}>-</button>
<button onClick={() => dispatch({type: 'increment'})}>+</button>
```

Full codes - 
```javascript
function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return {count: state.count + 1};
    case 'decrement':
      return {count: state.count - 1};
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, {count: 0});
  return (
      {state.count}
      <button onClick={() => dispatch({type: 'decrement'})}>-</button>
      <button onClick={() => dispatch({type: 'increment'})}>+</button>
    </>
  );
}
```

Hope it will help you! :heart: