React Hooks are live. Here is your introduction
Tags: react, javascript
Published: 2019-02-07 12:15:42

---
title: React Hooks are live. Here is your introduction
published: true
description: Introducing React hooks in less than 5 minutes
tags: [react, javascript]
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ve4p5dq3kjzc3lcdkjqv.png
canonical_url: https://sebhastian.com/react-hooks-introduction
---

Classes can be a large barrier to learn React, [says](https://reactjs.org/docs/hooks-intro.html#classes-confuse-both-people-and-machines) React team. They don't minify very well and they make hot reloading unreliable. With React Hooks, you don't need to convert a function component into class component. You can use state and lifecycle methods _in the function component_.

**Okay, but what are hooks really?**

They are functions that let you ["hook" into](https://reactjs.org/docs/hooks-overview.html#but-what-is-a-hook) React internal state and lifecycle features _from function components_

**Great! How do I do that?**

First, Update your React and React DOM dependency in your project. Hooks are freshly released on React 16.8.0 today!

```
npm install --save react@^16.8.0 react-dom@^16.8.0
```

Now let's take a look on the `useState` hook. Here is the demo:

{% codesandbox r1ryxqwvjo %}

## `useState` hook

We need to have a simple class component with state for comparison. The easiest example I can imagine is of an input form:

```jsx
class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = { value: '' };
  }

  handleChange = event => {
    this.setState({ value: event.target.value });
  };

  render() {
    return (
      <form>
        <label>
          Name:
          <input
            type="text"
            value={this.state.value}
            onChange={this.handleChange}
          />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
```

Now let's rewrite it using `useState` hook. We'll import it from `react` package so we don't have to write `React.useState` all the time.

```jsx
import React, { useState } from 'react';
```

Now change our `NameForm` into a function component

```jsx
function NameForm(props) {}
```

`useState` hook takes one argument, which is the initial state, and it returns two values: the current state and a function that can be used to update the state. You can replace the state initialization in the constructor:

```jsx
this.state = { value: '' };
```

into this:

```jsx
function NameForm(props) {
  const [value, setValue] = useState('');
}
```
Notice the use of square brackets when state variable is declared. This is the ES6 "[array destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Array_destructuring)" syntax, and it means we're assigning the first value returned by useState to `value` and the second value to `setValue`.

So this means we have a state named `value` and we can update it by calling on `setValue` function. Let's use it on our render method:

```jsx
function NameForm(props) {
  const [value, setValue] = useState('');

  return (
    <form>
      <label>
        Name:
        <input
          type="text"
          value={value}
          onChange={event => setValue(event.target.value)}
        />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}
```

`Onchange` props no longer call a `handleChange` method, instead we have an arrow function that will call `setValue` function, which update our `state`. Oh, and unlike `this.setState` in the class component, updating a state variable using hooks _always replace it instead of merging it_

## Having multiple states?

Then call on `useState` as many times as you need.

```jsx
function SimpleForm(props) {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [age, setAge] = useState('');

  return (
    <form>
      <label>
        First Name:
        <input
          type="text"
          value={firstName}
          onChange={event => setFirstName(event.target.value)}
        />
      </label>
      <label>
        Last Name:
        <input
          type="text"
          value={lastName}
          onChange={event => setLastName(event.target.value)}
        />
      </label>
      <label>
        Age:
        <input
          type="number"
          value={age}
          onChange={event => setAge(event.target.value)}
        />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}
```

And that's it with `useState` hook, really!

## Setting initial state from props

Oh, it's so easy!

```jsx
function SimpleForm(props) {
  const [firstName, setFirstName] = useState(props.firstName);
  const [lastName, setLastName] = useState(props.lastName);
  const [age, setAge] = useState(props.age);

  //...
}

ReactDOM.render(
  <SimpleForm firstName="JOHN" lastName="Edward" age={30} />,
  document.getElementById('root')
);
```

## Can I use object in state?

Sure! Just as class `state` can accept object or array, `useState` can have them as well. But to make it work, let's add name props to your input elements. We also use [spread properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Spread_in_object_literals) to update our state.

```jsx
function SimpleForm(props) {
  //create object state
  const [form, setForm] = useState({
    FirstName: '',
    LastName: '',
    age: '',
  });

  const handleChange = event => {
    // use spread operator
    setForm({
      ...form,
      [event.target.name]: event.target.value,
    });
  };

  return (
    <form>
      <label>
        First Name:
        <input
          type="text"
          name="firstName"
          value={form.firstName}
          onChange={handleChange}
        />
      </label>
      <label>
        Last Name:
        <input
          type="text"
          name="lastName"
          value={form.lastName}
          onChange={handleChange}
        />
      </label>
      <label>
        Age:
        <input
          type="number"
          name="age"
          value={form.age}
          onChange={handleChange}
        />
      </label>
      <input type="submit" value="Submit" />
    </form>
  );
}
```

## What about array?

This one's a bit unusual, but yes, just like in class `state`. We'll use concat on array update.

```jsx
function SampleArrayState(props) {
  //create array state
  const [nameArray, setNameArray] = useState(['Carl']);

  const updateArray = () => {
    setNameArray(nameArray.concat('John'));
  };

  return (
    <React.Fragment>
      <button onClick={updateArray}>Click me!</button>
      <div>{nameArray.toString()}</div>
    </React.Fragment>
  );
}
```

## And Boolean?

Got you covered here:

```jsx
function SampleBooleanState(props) {
  const [show, setShow] = useState(true);
  const visibility = show ? 'visible' : 'hidden';

  return (
    <React.Fragment>
      <h1 style={{ visibility }}>useState Hook is awesome!</h1>
      <button
        onClick={() => { setShow(!show) }}
      >{`${show ? 'Hide' : 'Show'} the Header!`}</button>
    </React.Fragment>
  );
}
```

## The rules of hooks
The important thing to remember is that hooks don't work in a class component. They are made for function components. 

1. Don't call hooks from inside nested function, loops or conditionals.
1. Don't call hooks from regular JavaScript function.
1. This [![no refactoring](https://sebhastian.com/static/c779ccfd84278ee7d5012527df3b370c/92de2/no-refactoring.png)](https://news.ycombinator.com/item?id=19094170)

## Conclusion

The `useState` hook enables function components to access React's internal state and update it. The state can be any data type: string, number, boolean, array, or object. `useState` accept one argument: the initial data, and it returns an array of two values: the current state value and the function/ method that can be used to update the state.

There are more than just `useState` hook, but let's cover each hook in their own single post.

Here's a list of all [built-in hooks](https://reactjs.org/docs/hooks-reference.html) (yes, you can write a custom hook!) available as of this writing. I'll be covering them in the next posts!

_Also, I'm writing a book on learning React properly without the stress. You might wanna check it out [here](https://sebhastian.com/react-distilled/)._

Until next time!

<a href='https://sebhastian.com/react-distilled'><img src="https://sebhastian.com/cta-react-distilled.jpg"></a>