React
Posted By Sebastian

Modern React From The Beginning EP9: Using The Effect Hook


Subscribe On YouTube

Episodes

So far we’ve made use of the useState Hook which enables us to create state within our functional components. We’ve used the concept of state to manage the user input in the search field and generate a filtered list of courses based on the state value.

In this episode we’re going to cover another React Hook: the useEffect hook. By using this hook you’ll be able to handle side-effects in your application very easily. So what is a side-effect? Before answering this questions let’s get into a first example to better illustrate the problem.

Using Local Storage To Persist The Search Text

If you’d like to persist the search text which has been entered by the user in the browser (so, that the input field value remains after the page has been reloaded) you can use the browser’s local storage very easily:

  const [searchText, setSearchText] = useState(
    localStorage.getItem('searchText') ||  ''
  );

  const handleSearch = event => {
    setSearchText(event.target.value);
    localStorage.setItem('searchText', event.target.value);
  };

In this case we’re setting a new local storage item with key searchText in the handleSearch function. The value of this item is set to the value of the input element.

When initializing the searchText state we’re trying to access the local storage item and use the value for setting the state. If this item is not existing in local storage we’re automatically setting the initial state value to an empty string.

As we’re reading the initial value for searchText from the local storage now, we need also to make sure that this value is displayed in the input fields. Therefore we need to pass the state value to Search component via another prop:

<Search value={searchText} onSearch={handleSearch} />

The value prop of Search component contains now the current value of searchText state, so that we’re able to use this prop for initialising the input field value:

import React from 'react';

const Search = ({value, onSearch}) => (
    <div>
        <label htmlFor="searchInput">Search: </label>
        <input  id="searchInput"
                type="text"
                value={value}
                onChange={onSearch} />
    </div>
);

export default Search;

When opening up the application in the browser you can get a glimpse on what’s happing in local storage if you open up the development tools too:

10.png

As you type in the search text input field you’ll see that the value for key searchText in local storage is updated and reflecting the value of the input field. By reloading the website you can see that the search text input field is prefilled with the value stored in local storage.

So, what’s the problem with that approach? We’ve used the event handler function to also update the value in the local storage. Herewith we want to make sure that the value in local storage is always in sync with the searchText state value. However updating of local storage is taking place in the handleSearch function. If we’re going to update searchText state somewhere else we need to make sure that local storage is updated as well. Updating the local storage can be seen as a side-effect of updating the state. If we can find a way of registering this action as a side-effect which is always taking place when the state is updated it would be a much better way. Therewith we would also be able to avoid the risk of forgetting to update local storage when changing the state value.

By using the React Effect Hook (useEffect) we can exactly to that. We’ll explore how this works in the following steps.

Persisting Search Text Using An Effect Hook

To be able to make use of the useEffect hook we need to extend the first import statement in App.js to the following:

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

Then we’re able to call the useEffect function:

const handleSearch = event => {
    setSearchText(event.target.value);
};

useEffect(() => {
    localStorage.setItem('searchText', searchText)
}, [searchText]);

The useEffect function expects two parameter. The first parameter is a function which contains the code of the side-effect. The second parameter is an array of dependant variables for which the side-effect should be registered. In our example the array contains the searchText state variable. This means that the function is executed each time the value of the searchText state variable changes. The side-effect can be registered for multiple variable at once. In this case the you can extend the array to contain more items. If the array is empty the side effect function is executed just once at the beginning of the component’s lifecycle.

The side-effect function contains the line of code which is needed to update the local storage with the current searchText value. This line of code can then be removed from the handleSearch function. Now we’ve made sure that everytime searchText is updated with a new value the search text value which is stored in local storage is updated as well.

Advertisement: Top 3 React Online Courses

If you want to dive deeper and become a React pro also consider taking one of the following great online courses.

React – The Complete Guide (incl Hooks, React Router, Redux)*
Dive in and learn React.js from scratch! Learn Reactjs, Hooks, Redux, React Routing, Animations, Next.js and way more!

Go To Course*

Modern React with Redux*
Master React v16.6.3 and Redux with React Router, Webpack, and Create-React-App. Includes Hooks!

Go To Course*

The Complete React Developer Course (w/ Hooks and Redux)*
Learn how to build and launch React web applications using React, Redux, Webpack, React-Router, and more!

Go To Course*

* Affiliate Link / Advertisement: This blog post contains affiliate links, which means that if you click on one of the product links and buy a product, we’ll receive a small commission. There are no additional costs for you. This helps support the channel and allows us to continue to make videos like this. Thank you for the support!


Using and writing about best practices and latest technologies in web design & development is my passion.