DEV Community

Cover image for Hooks: the kind that don't hurt ya
Larry Schwall
Larry Schwall

Posted on • Edited on

Hooks: the kind that don't hurt ya

Introduced in version 16.8, React hooks adds an advantage to stateless (functional) components. This advantage being the ability to manage state and use life-cycle events inside of these functional components. Adding hooks helps in the development of an app as a whole, as it reduces complexity and less codes. It solidifies a clean screen of code lines and a "easier to read" data flow.

Typically if we needed to write any form of state or lifecycle events we would have to switch from stateless/functional components to a class/stateful component. However, hooks allows us to avoid this completely.

Why use hooks?

React hooks allow the user to access state and life cycle events inside of stateless components, without actually having to bind or write the typical

this.state = {
example: exampleData, 
}
Enter fullscreen mode Exit fullscreen mode

instead we can use something in our stateless components like this

const [example, setExample] = useState();
Enter fullscreen mode Exit fullscreen mode

Hook Types

Below we will introduce some uses of state and lifecycle methods that can help you overall!

useState()

import React, { useState } from 'react'

const Example = () => {
    const [exampleSearch, setExampleSearch] = useState('');

    return (
        <div>
            <input onChange={(e) => {setExampleSearch(e.target.value)}} />
            </div>
    );
} ;
export default Example;
Enter fullscreen mode Exit fullscreen mode

The most prominent and primary React hook method is useState. To use it, you must first import it like above. In the above lines of code, we can see how much easier it is to use this is a functional component. To construct a useState consists of declaring an array. The first portion is the new state you wish to fill with date. The second portion being the function fills the first with data. The useState is passed an argument inside of the ( ). This argument is the starting state: an empty string, empty array, empty object, etc.

The useState uses something called destructuring for arrays. The same theory is applied to objects when using props. We can use many useStates in the same fashion to help build a dynamic site or application.

useEffect()

import React, { useState, useEffect } from "react";
const Example = () => {
    const [dataExample, setDataExample] = useState([]);
    useEffect(() => {
        fetch("route or endpoint")
        .then(response => response.json())
        .then(data => DataExample(data));
    });
    return (
    <div>
        <ul>
            {data.map(el => (
            <li key={el.name}>{el.age},{el.desc},{el.projects}</li>
            ))}
        </ul>
    </div>
    );
}
export default Profile;
Enter fullscreen mode Exit fullscreen mode

This hook is the perfect place to add something called listeners. If you have some sort of data fetching, posting, deleting, updating, etc, this is the place to do it. Think of useEffect() as your componentDidmount(){}, componentDidUpdate(){}, componentWillMount(){}. This is the first item to load on the page before any rendering. The effect hook adds the ability to grab the data from backend server code and allow the front end to see it on load. This is how hooks simplifies the idea of stateful components.

useRef()

Take a look at the example below

import React, { useRef } from "react";

const Fieldfocus = () => {

    const inputElement = useRef()

    const focusInput = () => {
        inputElement.current.focus()
        console.log('indirect!')
    }

    const focusing = () => {
        console.log('direct!')
    }

    return (
        <>
            <input onFocus ={focusing} ref={inputElement} type="text" />
            <button onClick={focusInput}>Add Focus</button>
        </>
    )
}
export default Fieldfocus;
Enter fullscreen mode Exit fullscreen mode

The useRef() hook helps us to allow access directly to a DOM element. It lets us create mutable variable inside the stateless. This hook will only be made when the component fully mounted and will be preserved during the full lifecycle.

NOTE: Updating a reference used inside of the useRef should be done inside of the useEffect() as it is considered a side effect.

useCallback()

import React, { useState, useCallback } from 'react';

const Button = (props) => {
    return <button onClick={props.onClick}>name</button>
}

const Example = ( ) => {
    const [counter, setCounter] = useState(0);
    const [active, setActive] = useState(false);    

    const countHandler = useCallback(() => setCounter(counter + 1), [counter]);
    const showHandler = useCallback(()=> setActive(!active), [active]);

    return (
        <div>
            {active && (
                <div>
                    <h3> {counter}</h3>
                    <button onClick={countHandler} />
                </div>
            <Button onClick={showHandler} name={active ? "hide" : "show" />
        </div>
    )
}
export default Example;
Enter fullscreen mode Exit fullscreen mode

This hook returns a memoized callback. It is also helpful when we have a child element that is frequently rerendering in our application. We can pass a callback to it. useCallBack() often is used with useEffect because it can prevent recreation of an element or action.

The only time the recreation happens with useCallback() is when one of the dependencies changes.

In Conclusion

As you can see, React hooks are very useful. The allow you to turn stateless components into stateful components with two lines of code. There are many more life cycle methods for hooks, the ones listed above are the most useful. Hopefully this guide has helped you to better understands hooks and their usefulness!

Top comments (0)