Awesome React Hooks, part 1, useState 
Tags: reactreacthooks
Published: 2018-10-30 15:48:27

---
title: Awesome React Hooks, part 1, useState 
published: true
description: an introduction post about useState hook in react
tags: react react-hooks
cover_image: https://images.unsplash.com/photo-1472235477785-4a74ac750010?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=e0fb6579cb8c6bc227e5393b2d113c19&auto=format&fit=crop&w=1350&q=80
---



So, if you follow the react community right now, we are on fire !

Please welcome an incredible thing for functional components: **hooks**

## What is a hook ?

Till now, we, react developpers, made the distinction between stateless components (functions) and stateful ones (classes).

With hooks, we got a set of primitive that will help us to interact with local state, side effects, ... for **functional** components.

This post is the first in a series that will cover the available react-hooks.

## useState hook

Let's start with a very useful and easy one:

```
useState
```

Hooks are available from the `16.7.0-alpha.0` tag onward on npm, so you can run:

```
npm install --save react@16.7.0-alpha.0 react-dom@16.7.0-alpha.0
```

or use a online editor to test 'em:


(playground)[https://stackblitz.com/edit/react-avqzi1]

With this trivial example, we can demonstrate the main features of the useState hook:

```js
import { useState } from 'react';

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useState(0);

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

When we call `useState(initialValue: any)`, this will return an array of 2 elements:

- first the actual current value of the data
- second is a function that let you change the data.

At first the count is equal to 0, and each time we call setCount(count + 1), **a rerender will occur** !

If you ever used `withState` from recompose, this is basically the same things except: 
- this is much simpler to reason about
- you don't complexify your tree with another layer of indirection,


One thing to note is that the generated state is **isolated**. With Hooks we are able to reuse *state logic* and not *state data*.

So if you call again useState (or use generated useState from a custom hook [more of this later] ), you will refer to another data cell !

## Concrete Application: Validation

The most interesting part is that I can generate a hook from another function that could be reused in differents components.

As useState is mapped to the 'rerendering' lifecycle of the component, we can reason about it very easily.

```js

function setWithValidation(businessRule, setValidated, setData) {
        // simple IOC
        // create a new function that is able to set validated state and change the data value
        return newValue => {
            setValidated(businessRule(newValue))    
            setData(newValue)
        }
}

function withValidation(businessRule) {
    return initialData => {
        // create an data cell for the main data we need
        const [data, setData] = React.useState(initialData)
        // create a data cell for the validation state
        const [validated, setValidated] = React.useState(businessRule(initialData))
        // return in a nice object, the data, a modified set function and the validated state
        return {data, set: setWithValidation(businessRule, setValidated, setData), validated}
    }
}
```

Now I have a flexible data cell that can validated !
The usage is trivial:

```js

function isEven(value){ return value % 2 === 0}

const useEvenData = withValidation(isEven)

function Example() {
  // Declare a new state variable, which we'll call "count"
  const {data, validated, set} = useEvenData(0);

  return (
    <div>
      <p>You clicked {data} times</p>
        {validated ? <p>The number is even</p> : <p>The number is odd :-(</p> }
      <button onClick={() => set(data + 1)}>
        increment
      </button>

      <button onClick={() => set(data -1)}>
        decrement
      </button>
    </div>
  );
}
```

You can try it here: 

[Online example](https://stackblitz.com/edit/react-hooks-simple-validation)

> Beware, you cannot use a hook outside a context of a component. Also place it at the top level of your component (not inside a loop, conditionnal...)


That's it ! Feel free to comment and see you in the part 2, with **side effects hooks**.


{% link https://dev.to/tclain/awesome-react-hooks---part-2---useeffect-29ao %}

### Links

https://reactjs.org/docs/hooks-intro.html
https://reactjs.org/docs/hooks-overview.html