React hooks introduction
Published: 2023-04-21 01:15:58

######Life before hooks was messy, confusing at times and full of repetitive code. With the implementation of React Hooks in early 2019, React v16.8.0 made the library simpler and more efficient. React soon became the most popular client-side framework/library for front-end development. 
---
## What are hooks and how did they impact React?

React hooks are special functions that let developers "hook into" React state and lifecycle features from functional components. Hooks allow you to reuse stateful logic without changing your component hierarchy. Hooks help to break down components into smaller functions based on their logic and relation. Hooks thus reduce the need for classes while letting you use more of React's features. They don't require you to learn complex functional or relative programming techniques making react a practical library.  

Previously React relied on class components to handle state, and without a simpler stateful primitive other than class components, React relied on creating a good amount of boiler plate to define the components. As a result code became cluttered, debugging became harder and logic becoming confusing. When trying to breakdown larger components proved difficult, as component logic became scattered, many felt that React had too much of a learning curve. More issues arose as learning how `this` works in JavaScript, having to remember to bind event handlers and struggling when to use classes over functions continued to deter developers from using the library. However hooks changed things for the better. 
 ---
## When should hooks be used? 
Hooks cover all existing use cases for classes as they provide a simpler implementation of state and lifecycle uses.

Displaying a stateful variable like a `username`, went from a cluttered logical mess, to a more concise component.

With a simple React class component there is a significant amount of boilerplate needed for the code to run:

```javascript
import React from 'react'

export default class Example extends React.Component{
    constructor(props) {
        super(props) ;
        this.state = { 
            username: '',
        }
    this.handleChange = this.handleChange.bind(this);
  }

    handleChange(e) { 
        this.setState({
            username: e.target.value
        });
    }

    render(){
        return (
            <>
                <h1>Welcome, {this.state.username}</h1>
                <input 
                value={this.state.username}
                onChange={this.handleChange}
                placeholder="Enter Username">
                </input>
            </>
        )
    }
}
```
Understanding how `this` works is essential, and the logic could quickly become confusing.

Using React hooks however makes the code quick, simple and allows for an easier understanding of how React state works:

```javascript
import React, {useState} from 'react'

function App() {
const [username, setUsername] = useState("")

function handleChange(e){setUsername(e.target.value)}
  return (
    <>
      <h1>Welcome, {username}</h1>
      <input 
       value={username}
       onChange={handleChange}
       placeholder="Enter Username"></input>
    </>
  )
}

export default App
```

**Hook limitations:** Classes allow for more customizable components, when compared to components using hooks. However, the React team thought of this and provided us with a method to create [custom hooks.](https://react.dev/learn/reusing-logic-with-custom-hooks)


***

##Main Hooks:

###1. useState:
 Like any other React hook `useState` must be imported from React at the top of the file:
```js
import {useState} from 'react';
```
Then called at the top level of your component declaring the state variable. When declaring state, specific syntax `[` and `]` is required to destructure the array as `useState` returns two values in an array: 
```js
function Component (){
    const [] = useState();
}
```
The first value is a state variable which, during the first render, will match the initial state that has been passed.
The second is the setter function that lets you update the state to a different value and trigger a re-render: 

**Note:** it is common practice to put `set` and then the name of the state variable in camelCase when naming variables.

```js
    const [age, setAge] = useState()
```
A value is then needed for the initial state, this value can be any value type with a special case for [functions](https://react.dev/reference/react/useState#parameters):

```js
    const [name, setName] = useState('Henry')
```
In order to use the setter function and change the current state of the state variable we must call the set function with some next state: 
```js
function handleClick(){
    setName('George')
}
``` 
***Note:*** when calling the set function the current state does not change the already executing code but rather changes what will be returned on the next render. 

When everything is all put together it looks something like this: 
```js
import {useState} from 'react' 

function Component(){
    const [age, setAge] = useState(28);
    const [name, setName] = useState(Sam); 

    function handleClick(){
        setAge(22);
        setName('George');
    }
//...
}
```
---
###2. useEffect:
This React hooks lets you synchronize a component with an external system. 

`useEffect` must be imported and called at the top level of your component to declare an Effect: 
```js
import {useEffect} from 'react';

function Component () {
    useEffect()
}
```
The `useEffect` hook takes two parameters, the first being a `setup` function that will handle your effects logic. When the component is first added to the DOM, React will run the `setup` function and continue running the function with each re-render.

```js
useEffect( ()=>{console.log('hello'},)
```
The second parameter is the dependency or dependencies  put into an array `[]` that has been declared previously. If no dependency is specified then the effect will continue executing indefinitely. An empty dependency can be use to execute the effect once on the first render: 
```js
useEffect( ()=>{console.log('hello')} , []) 
``` 
**Note:** Ensure that when thinking of using the `useEffect` hook you are trying to connect your component to some external system. In order to limit any unnecessary renders make sure your objects or other dependencies are necessary. 

When everything is put together it looks something like this: 
```js
import {useEffect, useState} from 'react';

function Component () {
    const [data, setData] = useState({});

    useEffect(()=>{ 
        fetch('https://localhost:3000')
        .then(r => r.json)
        .then( (newData) => setData(newData))

 },[])
}
```
---
###3. useContext:
This React hook lets you read and subscribe to context from your component. 
It needs to be imported at the top of the file and called at the top level of the component: 
```js
import {useContext} from 'react'

function Component (){
    useContext();
}
```
`useContext` takes one parameter, the context that has been previously created with [createContext](https://hy.reactjs.org/docs/context.html) at a previous component higher up on the component tree: 
```js
const page = useContext(pageContext) 
```
The returned value will be the context value for the calling component, this value is determined as the closest corresponding `Context.provider` above in the tree. When everything is put together it looks something like this: 
```js
import { createContext, useContext } from 'react';

const ThemeContext = createContext(null);

function Form() {
  return (
    <Panel title="Welcome">
      <Button>Sign up</Button>
      <Button>Log in</Button>
    </Panel>
  );
};

function Panel({ title, children }) {
  const theme = useContext(ThemeContext);
  return (
    <section className='panel'}>
      <h1>{title}</h1>
      {children}
    </section>
  )
};

function Button({ children }) {
  const theme = useContext(ThemeContext);
  return (
    <button className='button'>
      {children}
    </button>
  );
};

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <Form />
    </ThemeContext.Provider>
  )
};

export default App
```
***
For a more in-depth breakdown of these and all other hooks visit the [React docs](https://react.dev/reference/react) reference page for hooks.