Everything you need to know about React Hooks

Everything you need to know about React Hooks

In this React Hook tutorial, we will learn about the basics and fundamental knowledge of React Hook. What is react hooks and how we use hook functions within react functional components. Learn how to manage state within a component using useState hook function. Learn how to handle component lifecycle using react hooks. Learn about few hooks those are, useState and useEffect hooks.

React just announced a new feature: Hooks. It’s a brand new set of APIs that enables powerful new ways to share stateful logic between components, optimize performance without significant rewrites, get some of the benefits of Redux-style separation of concerns, and more.
It’s been a long time coming, but they’re here! More than just state, though, there are 11 new functions in all that should enable the full range of functionality that we use classes and the lifecycle for today.

  • useState
  • useEffect
  • useContext
  • useCallback
  • useMemo
  • React.memo (Not a hook, but new)
  • useReducer
  • useRef
  • useLayoutEffect
  • useImperativeMethods
  • useMutationEffect

Let’s take a look at what each of them is for.

useState

Stateful function components are enabled with the new function useState.

import { useState } from "react";const SomeComponent = props => {
  const [state, setState] = useState(initialState);  return (
    <div>
      {state} <input onChange={e => setState(e.target.value)} />
    </div>
  );
};

If you ever used the library recompose, this API may look familiar. useState takes an initial state as an argument, and returns the current state and an updater function. The setState it returns is almost the same used by class components—it can accept a callback that gets the current state as an argument, but it doesn't automatically merge top-level object keys.

Each call to useState is paired with a component, with its state persisting across renders. This means that you can call useState multiple times within a single function component to get multiple independent state values. Because the setState returned isn't scoped to a single component, we can define stateful behaviors independent of the component. This enables powerful new ways to abstract stateful logic.

Let’s look at an example that I’ve run into on several projects: managing sort state in several components. I find the APIs that table components expose to be inflexible, so I tend to write tables of data as one-offs. My current project has some code for managing what key to sort against, and in which direction, copy-pasted into several different components. With useState, we gain the ability to define it as a separate module.

const useSort = (someArray, initialSortKey) => {
  const [state, setState] = useState({
    isAscending: false,
    sortKey: initialSortKey
  });

  // Let's pretend `makeSortComparator` exists for simplicity
  const comparator = makeSortComparator(state);
  const sortedData = someArray.slice().sort(comparator);  return {
    ...state,
    sortedData,
    toggleAscending: () =>
      setState(state => ({
        ...state,
        isAscending: !state.isAscending
      })),
    setSortKey: sortKey =>
      setState(state => ({ ...state, sortKey }))
  };
};

Now we have a reusable method to use in our data table components. We have a simple API we can use across our many different tables, with each component working off its own separate state.

const SomeTable = ({ data }) => {
  const { sortedData, ...sortControls } = useSort(
    data,
    "id"
  );  return (
    <table>
      <TableHeading {...sortControls} />
      <tbody>
        {sortedData.map(datum => (
          <TableRow {...datum} />
        ))}
      </tbody>
    </table>
  );
};

Please note: the React team strongly recommends prefixing the names of these types of modules with use so there's a strong signal of what kind of behavior it provides. See the full docs for more about writing your own hooks.

I am super excited about this new way to share functionality. It’s much more lightweight than a HOC in all ways; less code to write, fewer components to mount, and fewer caveats. Check out the API documentation for all the details.

useEffect

A lot of components have to kick off different types of effects as part of mounting or re-rendering. Fetching data, subscribing to events, and imperatively interacting with another part of the page are all common examples of this. But the code for handling these types of effects ended up scattered across componentDidMount, componentDidUpdate, and componentWillUnmount.

If you wanted to run the same effect when a prop changed, you either had to add a mess of comparisons in componentDidUpdate or set a key on the component. Using a key simplifies your code, but it scatters control of effects into another file—completely outside the component's control!

useEffect simplifies all these cases. Imperative interactions are simple functions run after each render.

const PageTemplate = ({ title, children }) => {
  useEffect(() => {
    document.title = title;
  });  return (
    <div>
      <h1>{title}</h1> {children}
    </div>
  );
};

For data fetching and other interactions you don’t want to happen unnecessarily, you can pass an array of values. The effect is only run when one of these changes.

const ThingWithExternalData = ({ id, sort }) => {
  const [state, setState] = useState({});
  useEffect(
    () => {
      axios
        .get(`/our/api/${id}?sortBy=${sort}`)
        .then(({ data }) => setState(data));
    },
    [id, sort]
  );  return <pre>{JSON.stringify(state, null, 2)}</pre>;
};

Subscriptions and other effects that require some kind of cleanup when the components unmount can return a function to run.

const ThingWithASubscription = () => {
  const [state, setState] = useState({});
  useEffect(() => {
    someEventSource.subscribe(data => setState(data));
    return () => {
      someEventSource.unsubscribe();
    };
  });
  return <pre>{JSON.stringify(state, null, 2)}</pre>;
};

This is so powerful. Just like with useState, they can be defined as separate modules—not only does this put all the code required for these complex effects in a single location, they can be shared across multiple components. Combined with useState, this is an elegant way to generalize logic like loading states or subscriptions across components.

useContext

The context API is great and was a significant improvement in usability compared to what existed before. It advanced context from a “you probably shouldn’t use this” warning in the docs to an accepted part of the API. However, context can be cumbersome to use. It has to be used as a render prop, which is a pattern that doesn’t compose gracefully. If you need values out of multiple different render props, you quickly end up indented to the extreme.

useContext is a substantial step forward. It accepts the value created by the existing React.createContext function (the same one you would pull .Consumer off to use as a render prop) and returns the current value from that context provider. The component will rerender whenever the context value change, just like it would for state or props.

// An exported instance of `React.createContext()`
import SomeContext from "./SomeContext";const ThingWithContext = () => {
  const ourData = useContext(SomeContext);
  return <pre>{JSON.stringify(ourData, null, 2)}</pre>;
};

This gets rid of my final complaint with context. This API is simple and intuitive to the extreme and will be a powerful way to pipe state around an application.

More advanced hooks

The 3 hooks mentioned above are considered to be the basic hooks. It’s possible to write entire applications using only useState, useEffect, and useContext--really, you could get away with just the first two. The hooks that follow offer optimizations and increasingly niche utility that you may never encounter in your applications.

useCallback

React has a number of optimizations that rely on props remaining the same across renders. One of the simplest ways to break this is by defining callback functions inline. That’s not to say that defining functions inline will cause performance problems — in many cases, it has no impact. However, as you begin to optimize and identify what’s causing frequent re-renders, you may find inline function definitions to be the cause of many of your unnecessary prop change.

In the current API, changing an inline function to something that won’t change across renders can be a significant change. For function components, it means rewriting to a class (with all the changes that entails) and defining the function as a class method. useCallback provides a simple way to optimize these functions with minimal impact on your code by memoizing a function provided to it. Just like useEffect, we can tell it what values it depends on so that it doesn't change unnecessarily.

import doSomething from "./doSomething";const FrequentlyRerenders = ({ id }) => {
  return (
    <ExpensiveComponent
      onEvent={useCallback(() => doSomething(id), [id])}
    />
  );
};

This is another exciting improvement in usability. What used to mean a significant rewrite of a component can now be accomplished in-place with a function directly from React.

useMemo

On the subject of optimizations, there’s another hook that has me excited. Many times, I need to calculate derived data from the props I provide a component. It may be mapping an array of objects to a slightly different form, combining an array of data to a single value, or sorting or filtering. Often render is the logical place for this processing to happen, but then it will be run unnecessarily whenever other props or state change.

Enter useMemo. It's closely related to useCallback, but for optimizing data processing. It has the same API for defining what values it depends on as useEffect and useCallback.

const ExpensiveComputation = ({
  data,
  sortComparator,
  filterPredicate
}) => {
  const transformedData = useMemo(
    () => {
      return data
        .filter(filterPredicate)
        .sort(sortComparator);
    },
    [data, sortComparator, filterPredicate]
  );
  return <Table data={transformedData} />;
};

I’m excited about this for many of the same reasons as useCallback. Previously, optimizing this type of processing typically meant extracting the logic to a separate function and memoizing that. Because it's common practices for memoization tools to rely on a functions arguments for invalidating memoization, that meant creating a pure function. This refactoring can end up being too substantial, so only the most extreme performance problems end up being addressed. This hook should help avoid the "death by a thousand cuts" type of performance problems.

React.memo

This isn’t a hook, but it’s a new API and an important optimization. Memoizing calculations and ensuring props don’t change unnecessarily are good for performance, but both are more effective when combined with the shouldComponentUpdate or PureComponent features—neither of which is available for function components.

React.memo is a new function that enables behavior similar to PureComponent for functions. It compares prop values and only re-renders when they change. It doesn't compare state or context, just like PureComponent. It can accept a second argument so you can do custom comparisons against props, but there's an important difference from shouldComponentUpdate: it only receives props. Because useState doesn't provide a single state object, it can't be made available for this comparison.

useReducer

This hook has interesting implications for the ecosystem. The reducer/action pattern is one of the most powerful benefits of Redux. It encourages modeling UI as a state machine, with clearly defined states and transitions. One of the challenges to using Redux, however, is gluing it all together. Action creators, which components to connect(), mapStateToProps, using selectors, coordinating asynchronous behavior... There's a whole menagerie of associated code and libraries on top of Redux that can overwhelm.

useReducer, combined with the usability improvements to context, new techniques for memoizing calculations, and the hooks for running effects, allow for many of the same benefits as Redux with less conceptual overhead. I personally have never been bothered by the supposed boilerplate problem that Redux has, but considering how these hooks will combine has me excited for how features could be defined and scoped within an application.

useRef

Sometimes when writing components, we end up with information that we need to keep track of but don’t want to re-render when it changes. The most common example of this is references to the DOM nodes we’ve created, for instance, an input node that we need to track the cursor position for or imperatively focus. With class components we would track assign them directly to properties on this, but function components don't have a context we can reference that way.

useRef provides a mechanism for these cases. It creates an object that exists for as long as the component is mounted, exposing the value assigned as a .current property.

Directly from the docs (and the FAQ:

// DOM node ref example
function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` points to the mounted text input element
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>
        Focus the input
      </button>
    </>
  );
}// An arbitrary instance property
function Timer() {
  const intervalRef = useRef();
  useEffect(() => {
    const id = setInterval(() => {
      // ...
    });
    intervalRef.current = id;
    return () => {
      clearInterval(intervalRef.current);
    };
  });
}

This code is more verbose than using instance properties is in class components, but it should be relatively infrequent that you need to store values in this way.

Rarely used hooks

The hooks mentioned above have covered all the use cases that I’ve encountered when writing applications. Reading through the docs of the remaining hooks, I understand why they exist and I’m sure that I’m using libraries that will implement them, but I don’t anticipate using them myself in application code.

useLayoutEffect

If I use any of these 3, I anticipate it will be useLayoutEffect. This is the hook recommended when you need to read computed styles after the DOM has been mutated, but before the browser has painted the new layout.

Crucially, this gives you an opportunity to apply animations with the least chance of visual artifacts or browser rendering performance problems. This is the method currently used by react-flip-move, an amazing transition library when items change position, but there might be situations where I need to use this myself.

useImperativeMethods

To the best of my knowledge, this hook is a counterpart to forwardRef, a mechanism for libraries to pass through the ref property that would otherwise be swallowed. This is a problem for component libraries like Material UI, React Bootstrap, or CSS-in-JS tools like styled-components, but I haven't run into a case where I needed to solve this problem myself.

useMutationEffect

This is the hook I’m having the hardest time wrapping my head around. It’s run immediately before React mutates the DOM with the results from render, but useLayoutEffect is the better choice when you have to read computed styles. The docs specify that it runs before sibling components are updated and that it should be used to perform custom DOM mutations. This is the only hook that I can't picture a use case for, but it might be useful for cases like when you want a different tool (like D3, or perhaps a canvas or WebGL renderer) to take over the actual rendering of output. Don't hold me to that though.

In conclusion

Hooks have me excited about the future of React all over again. I’ve been using this tool since 2014, and it has continually introduced new changes that convince me that it’s the future of web development. These hooks are no different, and yet again substantially raise the bar for developer experience, enabling me to write durable code, and improve my productivity by extracting reused functionality.

I thought Suspense was the only upcoming feature that I’d be excited for in 2018, but I’m happy to be proven wrong! Combined, I expect that React applications will set a new bar for end-user experience and code stability.

Video

React Hooks Tutorial for Beginners: Getting Started With React Hooks

React Hooks Tutorial for Beginners: Getting Started With React Hooks

React hooks tutorial for beginners, learn React hooks step by step: Introduction, useState Hook, useState with previous state, useState with object, useState with array, useEffect Hook, useEffect after render, Conditionally run effects, Run effects only once, useEffect with cleanup, useEffect with incorrect dependency, Fetching data with useEffect, useContext Hook, useReducer Hook, useReducer, Multiple useReducers, useReducer with useContext, Fetching data with useReducer, useState vs useReducer, useCallback Hook, useMemo Hook, useRef Hook

React Hooks Tutorial - 1 - Introduction

Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class.

React Hooks Tutorial - 2 - useState Hook React Hooks Tutorial - 3 - useState with previous state React Hooks Tutorial - 4 - useState with object React Hooks Tutorial - 5 - useState with array React Hooks Tutorial - 6 - useEffect Hook React Hooks Tutorial - 7 - useEffect after render React Hooks Tutorial - 8 - Conditionally run effects React Hooks Tutorial - 9 - Run effects only once React Hooks Tutorial - 10 - useEffect with cleanup React Hooks Tutorial - 11 - useEffect with incorrect dependency React Hooks Tutorial - 12 - Fetching data with useEffect Part 1 React Hooks Tutorial - 13 - Fetching data with useEffect Part 2 React Hooks Tutorial - 14 - Fetching data with useEffect Part 3 React Hooks Tutorial - 15 - useContext Hook Part 1 React Hooks Tutorial - 16 - useContext Hook Part 2 React Hooks Tutorial - 17 - useContext Hook Part 3 React Hooks Tutorial - 18 - useReducer Hook React Hooks Tutorial - 19 - useReducer (simple state & action) React Hooks Tutorial - 20 - useReducer (complex state & action) React Hooks Tutorial - 21 - Multiple useReducers React Hooks Tutorial - 22 - useReducer with useContext React Hooks Tutorial - 23 - Fetching data with useReducer Part 1 React Hooks Tutorial - 24 - Fetching data with useReducer Part 2 React Hooks Tutorial - 25 - useState vs useReducer React Hooks Tutorial - 26 - useCallback Hook React Hooks Tutorial - 27 - useMemo Hook React Hooks Tutorial - 28 - useRef Hook Part 1 React Hooks Tutorial - 29 - useRef Hook Part 2 React Hooks Tutorial - 30 - Custom Hooks React Hooks Tutorial - 31 - useDocumentTitle Custom Hook React Hooks Tutorial - 32 - useCounter Custom Hook React Hooks Tutorial - 33 - useInput Custom Hook

How to create reusable React components with React Hooks?

How to create reusable React components with React Hooks?

In this React components tutorial, we learn how to create reusable React components with React Hooks. Building reusable UI components with React Hooks. We’ll use Hooks for managing and manipulating state data.

In React, a reusable component is a piece of UI that can be used in various parts of an application to build more than one UI instance. For instance, we can have a button component display with different colors in several parts of our application. Although it is the same button component when we provide it with a dataset (e.g color, or a function), it modifies itself and outputs a UI instance of the element.

This pattern of creating React components is necessary for scaling. It helps save time by ensuring less code is written, development is faster, the codebase is simpler, and maintenance is stress-free.

In this tutorial, we will build reusable React components that can be used throughout your projects to maintain consistency in logic and presentation. We’ll use Hooks for managing and manipulating state data.

This post assumes you that you have a basic understanding of React. If you don’t have any experience using React, you can refer to the documentation here to get started.

Getting started

In this part of the tutorial, we will create various HTML elements as reusable components. We’ll be using CodeSandbox. You can create a new sandbox to get started:

Input component

One advantage of creating a reusable input component is that you maintain the appearance of the input in various parts of your application. You can also determine what type of input component should be rendered (text, email, etc) by passing it a prop. Although we won’t go deep into styling in this tutorial, you can customize your components to suit your visual needs.

In your newly created sandbox project, create a components folder with a FormInput.js file and add the following code to it:

// ./components/FormInput.js
import React, {useState} from "react";

function FormInput(props) {
  const [inputType] = useState(props.type)
  const [inputValue, setInputValue] = useState('')

  function handleChange(event){
    setInputValue(event.target.value);
    if(props.onChange) props.onChange(inputValue)
  }
  return (
    <>
      <input type={inputType} value={inputValue} name="input-form" onChange={handleChange} class="inputclass"/>
    </>
  );
}
export default TextInput;

For a component to be reusable, it has to take in data or data sets (via props) and return an output (usually through a function passed via props). It is recommended that mutable state should be kept in the state property of a component to ensure they work correctly.

The FormInput() component above receives an input type to determine what type of input element to render (email, text, etc). It also takes in a method onChange() to receive the value sent back out from the input.

The component manages its value locally, and only returns the updated state value to the component it is called from.

To achieve this, we created a local function handleChange(). The function checks if a method to receive the state data is available via props then sends the current state data to it for further processing.

Custom select component

In your components folder, create a CustomSelect.js file and add the following code to it:

// ./components/CustomSelect.js
import React, { useState } from "react";
function CustomSelect(props) {
  const [data] = useState(props.data);
  const [selectedData, updateSelectedData] = useState("");
  function handleChange(event) {
    updateSelectedData(event.target.value);
    if (props.onSelectChange) props.onSelectChange(selectedData);
  }
  let options = data.map(data => (
    <option key={data.id} value={data.id}>
      {data.name}
    </option>
  ));
  return (
    <select
      name="customSearch"
      className="custom-search-select"
      onChange={handleChange}
    >
      <option>Select Item</option>
      {options}
    </select>
  );
}
export default CustomSelect;

Above, we receive the data set needed for the options tag in the select element via props. To build the option tags, we looped through the data set via props to construct it before rendering it as part of the select tag.

The state of the tag (the currently selected option) is stored locally and updated and sent back as an output when it changes via our local function handleChange().

Button component

A reusable button can be used to display different color variants or sizes everywhere it is used in your application. In your components folder, create a Button.js file and add the following code to it:

// ./components/Button.js
import React, { useState } from "react";
function Button(props) {
  const [size] = useState(props.size);
  const [variant] = useState(props.variant);
  return (
    <button className={`btn-${variant} btn-${size}`}>{props.children}</button>
  );
}
export default Button;

Our button receives three properties via props. The variant (used to determine the button color), the size (lg, xs, sm) to determine the size of the button. We display the button content dynamically using React’s built-in children property (props.children).

Modal component

A modal component is suitable for sending alerts in your application. In your components folder, create a Modal.js file and add the following code to it:

// ./components/Modal.js
import React, { useState, useEffect } from "react";
function Modal(props) {
  const [message] = useState(props.message);
  const [show, setShow] = useState(props.show);
  useEffect(() => {
    setTimeout(() => {
      setShow(false);
    }, 3000);
  });
  return (
    <div className={show ? "modal display-block" : "modal display-none"}>
      <section className="modal-main">{message}</section>
    </div>
  );
}
export default Modal;

Our modal component does two things:

  • It receives a boolean value that determines if it pops up or not
  • It also receives the message to be displayed when it pops up

To close the modal, we’d need to set the show state to false. We can do that by calling a setTimeout() function in the [useEffect()](https://reactjs.org/docs/hooks-effect.html) hook after a few seconds.

Toggle component

A toggle component is used in situations where a true or false answer is necessary. It is an essential form component.

In your components folder, create a ToggleSwitch.js file and add the following code to it:

// ./components/ToggleSwitch.js
import React, { useState } from "react";
function ToggleSwitch(props) {
  const [checked, setChecked] = useState(props.defaultChecked);
  const [Text] = useState(props.Text);
  function onChange(e) {
    setChecked(e.target.value);
    if (props.onToggleChange) props.onToggleChange(checked);
  }
  return (
    <div className={"toggle toggle-switch"}>
      <input
        type="checkbox"
        name={props.Name}
        className="toggle-switch-checkbox"
        id={props.id}
        defaultChecked={checked}
        onChange={onChange}
      />
      {props.id ? (
        <label className="toggle-switch-label" htmlFor={props.id}>
          <span
            className={
              props.disabled
                ? "toggle-switch-inner toggle-switch-disabled"
                : "toggle-switch-inner"
            }
            data-yes={Text[0]}
            data-no={Text[1]}
          />
          <span
            className={
              props.disabled
                ? "toggle-switch-switch toggle-switch-disabled"
                : "toggle-switch-switch"
            }
          />
        </label>
      ) : null}
    </div>
  );
}
export default ToggleSwitch;

Our toggle component receives the following props:

  • ID (required): this is the ID that’s going to be passed to the checkbox input control. Without this, the component won’t render
  • Text (required): The Toggle Switch contains an array of two values, which signify the text for True and False
  • Name (optional): this will be label text of the checkbox input
  • onChange (optional): this will used to receive the returned data from the components
  • Checked (optional): this will be directly passed to the element to get its current state
  • Disabled (optional): this will be be used to set the state of the button

When it changes, we update the state and send the value to the event listener sent via props from the parent component.

Using the components

To use the components we just created, we need to render them from a parent component and pass the relevant data to them. Add the following to your index.js:

// ./index.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import FormInput from "../components/FormInput.js";
import CustomSelect from "../components/CustomSelect.js";
import ToggleSwitch from "../components/ToggleSwitch.js";
import Button from "../components/Button.js";
import Modal from "../components/Modal.js";
import "./styles.css";
function App() {
  const data = [
    {
      id: "1",
      name: "One"
    },
    {
      id: "2",
      name: "Two"
    },
    {
      id: "3",
      name: "Three"
    },
    {
      id: "4",
      name: "Four"
    }
  ];
  function handleChange(event) {
    console.log(event.target.value);
  }
  function onSelectChange(event) {
    console.log(event.target.value);
  }
  function onToggleChange(event) {
    console.log(event.target.checked);
  }
  return (
    <div className="App">
      <form>
        <Modal show={true} message={"Hello"}>
          <p>THIS IS A MODAL</p>
        </Modal>
        <FormInput type={"text"} onChange={handleChange} />
        <FormInput type={"email"} onChange={handleChange} />
        <div>
          <CustomSelect data={data} onSelectChange={onSelectChange} />
        </div>
        <div>
          <ToggleSwitch
            id="id"
            defaultChecked={false}
            disabled={false}
            Text={["Yes", "No"]}
            onToggleChange={onToggleChange}
          />
        </div>
        <Button variant="danger" size={"sm"} >Small Button</Button>
        <Button variant="primary" size={"lg"} >Smaller Button</Button>
        <Button variant="warning" size={"xs"} >Big Button</Button>
      </form>
    </div>
  );
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

And you should see the following:

Conclusion

In this tutorial, we learned how to create reusable React components. This knowledge can be applied to create highly scalable and consistent React applications. We also worked with Hooks to manage and manipulate state data. You can find all the code samples used in this post in the this CodeSandbox project:

To read more about Hooks and React components check out the docs here.

React Hooks: useState and useEffect in React.js Web Application

React Hooks: useState and useEffect in React.js Web Application

In this React Hooks tutorial, you'll see the real-world examples of React Hooks useState and useEffect in a React.js Web application. This React.js tutorial: React Hooks useState and useEffect Examples

The real-world examples of React Hooks useState and useEffect in a React.js Web application

In this React.js tutorial, we will show you the real-world examples of React Hooks useState and useEffect in a React.js Web application. Now, with these examples you will learn more deeply about a few essential React Hooks useState and useEffect.

Table of Contents:

  • Preparation
  • React Hooks useState Examples
  • React Hooks useEffect Examples
  • Run and Test the React Hooks useState and useEffect Examples

The following tools, frameworks, libraries, and modules are required for this tutorial:

  1. Node.js (with NPM or Yarn)
  2. React.js (min. version 16.8)
  3. Node-Express REST API
  4. Terminal or Node Command Line
  5. IDE or Text Editor (We are using Visual Studio Code)
Preparation

We need to prepare the environment for creating React.js application from the scratch, we assume you don't have any tools or frameworks installed on your computer. The first thing to do is install Node.js with NPM or Yarn. Just download the installer from official download page https://nodejs.org, choose recommended version for your OS. Install to your computer by following the install wizard. After Node.js installation finished, open your terminal (Mac OS/Linux) or Node command line (Windows) then check the installed Node.js and NPM.

node -v
v10.15.1
npm -v
6.13.1

If you plan to use Yarn, install it from the Terminal. On our Mac OS, we type this command.

brew install yarn

You can choose your desired installation method for your OS, you find the guide on the Yarn site. To check the installed yarn version, type this command.

yarn -v
1.19.2

Next, we will use the create-react-app tool. The create-react-app is a tool to create a React.js app from the command line or CLI. So you don’t need to install or configure tools like Webpack or Babel because they are preconfigured and hidden so that you can focus on the code. Type this command to install it.

sudo npm install -g create-react-app

Now, we can create a new React.js app using that tool.

create-react-app react-hooks-use

This command will create a new React app with the name react-hooks-use and this process can take minutes because all dependencies and modules also installing automatically. Next, go to the newly created app folder.

cd ./react-hooks-use

Open the project in your IDE or text editor and see the content of package.json.

"dependencies": {
  "react": "^16.12.0",
  "react-dom": "^16.12.0",
  "react-scripts": "3.2.0"
},

That React version is the version that already uses React Hooks as default. Now, src/App.js doesn't use class anymore. For sanitation, run this React app for the first time by type this command.

yarn start

And here' we go the latest React.js application that uses React Hooks with the same initial home page.

Next, we need to add the required component or page for each example. For that, add these directories and files inside the src directory.

mkdir src/hooks-state
mkdir src/hooks-effect
touch src/hooks-state/BasicState.js
touch src/hooks-state/MultipleState.js
touch src/hooks-effect/BasicEffect.js
touch src/hooks-effect/FetchEffect.js
touch src/hooks-effect/AxiosEffect.js
touch src/hooks-effect/ListenerEffect.js

Next, add the react-router-dom to make routing and navigation for these examples.

yarn add react-router-dom

Next, open and edit src/index.js then add these imports of Router and Route (react-router-dom) and all created components before the ./index.css import.

import { BrowserRouter as Router, Route } from 'react-router-dom';
import BasicState from './hooks-state/BasicState';
import MultipleState from './hooks-state/MultipleState';
import BasicEffect from './hooks-effect/BasicEffect';
import FetchEffect from './hooks-effect/FetchEffect';
import AxiosEffect from './hooks-effect/AxiosEffect';
import ListenerEffect from './hooks-effect/ListenerEffect';

Next, add to the React.DOM render.

ReactDOM.render(
    <Router>
        <div>
            <Route render ={()=> < App />} path="/" />
            <Route render ={()=> < BasicState />} path="/hooks-state/basic-state" />
            <Route render ={()=> < MultipleState />} path="/hooks-state/multiple-state" />
            <Route render ={()=> < BasicEffect />} path="/hooks-effect/basic-effect" />
            <Route render ={()=> < FetchEffect />} path="/hooks-effect/fetch-effect" />
            <Route render ={()=> < AxiosEffect />} path="/hooks-effect/axios-effect" />
            <Route render ={()=> < ListenerEffect />} path="/hooks-effect/listener-effect" />
        </div>
    </Router>, document.getElementById('root'));

Next, we will create navigation for all React Hooks useState and useState examples. Open and edit src/App.js then replace all "return" content with these.

return (
  <div className="App">
    <h2>React Hooks Examples</h2>
    <h3>useState Examples:</h3>
    <p><a href="/hooks-state/basic-state">Basic useState Example</a></p>
    <p><a href="/hooks-state/multiple-state">Multiple useState Example</a></p>
    <h3>useEffect Examples:</h3>
    <p><a href="/hooks-effect/basic-effect">Basic useEffect Example</a></p>
    <p><a href="/hooks-effect/fetch-effect">Fetch useEffect Example</a></p>
    <p><a href="/hooks-effect/axios-effect">Axios useEffect Example</a></p>
    <p><a href="/hooks-effect/listener-effect">Listener useEffect Example</a></p>
    <p><a href="/hooks-effect/resize-effect">Resize useEffect Example</a></p>
  </div>
);

Next, make all components file have an exported function name same as the file name as an example below.

import '../App.css';

function BasicState() {

  return (
    <div className="App">
    </div>
  );
}

export default BasicState;
React Hooks useState Examples

Before seeing the example, we try to make a little understanding of the React Hooks useState formula. It just simply like this line.

const [state, setState] = useState(initialState);

Which "state" is a variable, "setState" if a function that can change the variable, and "initialState" is an initial value of the variable.

Basic useState Example

Next, we need to implement the React Hooks basic useState. Open and edit src/hooks-state/BasicState.js then add useState to the react import.

import React, { useState } from 'react';

We will declare a variable of the string that has an initial value.

const [title, setTitle] = useState('Getting Started learning a React Hooks');

In this basic useState usage, we will put the "setTitle" that change the "title" value as a button action. Add/replace these lines to the React template to add a text and a button.

return (
  <div className="App">
    <h2>{title}</h2>
    <button onClick={() => setTitle('React Hooks in My Learning Path')}>
      Change Title
    </button>
  </div>
);

Multiple useState Example

This example is the multiple "useState" with different data types. Open and edit src/hooks-state/MultipleState.js then add useState to the react import.

import React, { useState } from 'react';

Add these multiple constant variables.

const [title, setTitle] = useState('Getting Started learning a React Hooks');
const [year, setYear] = useState(2019);
const [emails, setEmail] = useState([
  {name: 'my name', email: '[email protected]'},
  {name: 'my second name',email: '[email protected]'},
  {name: 'my third name',email: '[email protected]'},
  {name: 'my alias name',email: '[email protected]'}
]);

Replace the "return" content with these.

return (
  <div className="App">
    <h2>{title}</h2>
    <h2>{year}</h2>
    <dl>
      {emails.map((item, idx) => (
        <dd>{item.name}, {item.email}</dd>
      ))}
    </dl>
    <button onClick={() => {
      setTitle('Another React Hooks Book');
      setYear(2020);
      setEmail([
        {name: 'Ian Rush', email: '[email protected]'},
        {name: 'Roberto Baggio',email: '[email protected]'},
        {name: 'Thierry Hendry',email: '[email protected]'},
        {name: 'David Seaman',email: '[email protected]'}
      ]);
    }}>
      Change Title
    </button>
  </div>
);
React Hooks useEffect Examples

React Hooks useEffect is a single function that similar to componentDidMount, componentDidUpdate, and componentWillUnmount in React classes. We will show you an example of the useEffect in a real React application.

Basic useEffect Example

This basic useEffect example just changes the title when the component is loaded. Open and edit src/hooks-effect/BasicEffect.js then add this import of useState and useEffect.

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

Add a required constant variable that uses useState.

const [title, setTitle] = useState('React Hooks at a Glance');
const [year, setYear] = useState(2019);

Add this useEffect function before the return template.

useEffect(() => {
  setTitle(`The new articles of ${year}`);
});

Change the return content with these.

return (
  <div className="App">
    <h2>{title}</h2>
  </div>
);

Fetch useEffect Example

This example fetches data from the REST API you can run our Node-Express REST API and MongoDB server in your machine to implementing this example. Open and edit src/hooks-effect/FetchEffect.js then add this import of useState and useEffect.

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

Add a required constant variable that use useState.

const [product, setProduct] = useState(null);
const [url, setState] = useState(`http://localhost:3000/api/v1/products`);

Next, we will implement useEffect with a cleaning-up effect feature by adding an AbortController method at the useEffect return. Add this useEffect function after the constant variable.

useEffect(() => {

  let abortController = new AbortController();

  const loadProduct = async () => {
    try {
      const response = await fetch(url, { signal: abortController.signal });
      const data = await response.json();
      console.log(`Data fetched: ${data}`);
      setProduct(data);
    } catch (error) {
      console.log(`Error fetch data: ${error}`);
      throw error;
    }
  };

  loadProduct();

  return () => {
    console.log("Cancel fetch: abort");
    abortController.abort();
  };
}, [url]);

If you want to implement conditionally firing an effect, just change the end of the useEffect function to this.

useEffect(() => {
  ...
}, [product]);

Next, add a loading indicator before implementing the view template.

if (!product) {
  return <div className="App">Loading...</div>;
}

Modify the return to display the loaded data.

return (
  <div className="App">
    {product.map((item, idx) => (
      <p>{item.prod_name}</p>
    ))}
  </div>
);

Axios useEffect Example

This example same as the previous fetch example except we are using the Axios library to consume the REST API. First, we need to install that library by type this command in the terminal.

yarn add axios

Next, open and edit src/hooks-effect/AxiosEffect.js then add these imports of useState, useEffect, and Axios.

import React, { useState, useEffect } from 'react';
import Axios from "axios";

Add a required constant variable that uses useState.

const [product, setProduct] = useState(null);
const [url, setState] = useState(`http://localhost:3000/api/v1/products`);

Next, we will implement useEffect with a cleaning-up effect feature by adding an Axios.CancelToken.source() cancel method at the useEffect return. Add this useEffect function after the constant variable.

useEffect(() => {
  let source = Axios.CancelToken.source();

  const loadProduct = async () => {
    try {
      const response = await Axios.get(url, {
        cancelToken: source.token
      });
      console.log(response);
      setProduct(response.data);
    } catch (error) {
      if (Axios.isCancel(error)) {
        console.log("Cancel axios data source on error");
      } else {
        throw error;
      }
    }
  };

  loadProduct();

  return () => {
    console.log("Cancel axios data source");
    source.cancel();
  };
}, [url]);

Next, add a loading indicator before implementing the view template.

if (!product) {
  return <div className="App">Loading...</div>;
}

Modify the return to display the loaded data.

return (
  <div className="App">
    {product.map((item, idx) => (
      <p>{item.prod_name}</p>
    ))}
  </div>
);

Listener useEffect Example

This example of React Hook's useEffect is firing an effect based on Javascript DOM event listener. Right now, we will use the click event lister for the windows or screen element. Open and edit src/app/hooks-effect/ListenerEffect.js then add this import of useEffect.

import React, { useEffect } from 'react';

Next, we will implement the useEffect that firing by click event listener.

useEffect(() => {
  const listener = () => {
    console.log(`The screen is clicked`);
  };
  window.addEventListener("click", listener);

  return () => {
    window.removeEventListener("click", listener);
  };
}, []);

Next, modify the return to this HTML template.

return (
  <div className="App">
    <h4>Click the screen to listen the click event</h4>
  </div>
);
Run and Test the React Hooks useState and useEffect Examples

To run this React Hooks useState and useEffect examples, we need to run MongoDB server and Node-Express REST API first in another terminal tabs. Next, run this React Hooks example using custom port by type this command.

PORT=8080 yarn start

Now, the React Hooks useState and useEffect Examples run using Port 8080 that different from the Node-Express server. You can check the implementation of these examples one by one from this React home page.

That it's, the React Hooks useState and useEffect Examples. You can find the full source codes from our GitHub.

Thanks!