We offer private, customized training for 3 or more people at your site or online.
To follow along with this React tutorial, you can visit GitHub to download the code we will use. We have some setup instructions on the readme file for the repository for you to code along with this lesson.
In this tutorial, you will learn how to optimize the re-rendering of a component using the Callback Hook. We will start it up by typing 'npm start' in the App.js file. This will launch the application in your default web browser and you will see a simple application that allows us to add, edit, and delete cars. You will notice when we click the edit button, it will go to "edit" mode and if you click the cancel button, it will go back to "read only" mode.
Read Only Mode
Edit Mode
In CarForm.js, you will see we have a CarForm component. Here is where we are going to put a console log.
We will see 'rendering car form' each time this CarForm component function is called.
Now if we open our developer tools to the Console and click edit, it renders the car form again. Now, nothing changed in the car form, but it rendered the parent component app. This not only renders the app itself as well as the table, but renders any other components under it, including CarForm.
What can we do to improve the performance to only render CarForm when something is changing and being passed into CarForm? We could use the memo function.
I will go to line 4 and type 'memo' and then we can wrap everything in our memo function. The memo function will only surrender when we change the incoming props. It is a shallow comparison, but if you pass the same primitive values that are the same object references, it will only re-render when changed values are passed in.
If we reload now, you will see it still rendered it again. But why did it render when we are not changing this button text at all? Our button text is hard coded to addCar. The culprit here is the appendCar function on submit. Each time we called this app function, it produced a brand new appendCar function, which is a new object reference.
CarForm.js
Here is the code as shown in CarForm.js:
import React, { useState, memo } from 'react'; import PropTypes from 'prop-types'; export const CarForm = memo(({ buttonText, onSubmitCar, }) => { console.log('rendering car form'); const [ carForm, setCarForm ] = useState({ make: '', model: '', year: 1900, color: '', price: 0, });
Then that new object reference being passed is causing the memo function to think something has changed so it re-renders the component.
That is where the callback hook comes in. We can type useCallback (line 1) to remember the previous callback function so it will use the previous callback function instead of always producing a new one. We will wrap a callback around this function and this array (line 19) is going to represent dependencies with which we might be working. So, for example, the dependency here is the array of cars, which is what it's actually complaining about here. So instead, we could type 'cars' and save that.
App.js
Here is the code as shown in App.js:
import React, { useState, useCallback } from 'react'; import { carsPropType } from './propTypes'; import { ToolHeader, CarTable, CarForm } from './components'; export const App = ({ cars: initialCars, }) => { const [ cars, setCars ] = useState(initialCars.concat()); const [ editCarId, setEditCarId ] = useState(-1); const appendCar = useCallback(car => { setCars(cars.concat({ ...car, id: Math.max(...cars.map(c => c.id), 0) + 1, })); setEditCarId(-1); }, [ cars ]); const replaceCar = car => { const carIndex = cars.findIndex(c => c.id === car.id); const newCars = cars.concat(); newCars[carIndex] = car; setCars(newCars); setEditCarId(-1); }; const deleteCar = carId => { setCars(cars.filter(c => c.id !== carId)); setEditCarId(-1); }; const cancelCar = () => { setEditCarId(-1); };
Now watch what happens in the form. If we click Edit, you will see it did not rerender CarForm. If we click, cancel, it does not render CarForm. Now if we add a car, you will see the CarForm changes. Then if I click "Add Car" at the bottom, you will see it rendered it again. But it is only going to render CarForm if you are typing into it or if the actual underlying array of cars has changed.
In this short tutorial, you saw how to optimize the re-rendering of a component using Callback Hooks and the Memo function. As you can see, Callback Hooks and the Memo function make it easy to improve the performance of React components without having to use classes.
Accelebrate offers live, private React/Redux training for teams of 3 or more. For more information, please see our list of React courses.
The original React Callback Hooks 5-minute video for this tutorial was recorded by Eric Greene
Eric is a professional software developer specializing in HTML, CSS, and JavaScript technologies. He has been developing software and delivering training classes for nearly 19 years. He holds the MCSD Certification for ASP.NET Web Applications and is a Microsoft Certified Trainer.
Our live, instructor-led lectures are far more effective than pre-recorded classes
If your team is not 100% satisfied with your training, we do what's necessary to make it right
Whether you are at home or in the office, we make learning interactive and engaging
We accept check, ACH/EFT, major credit cards, and most purchase orders
Alabama
Birmingham
Huntsville
Montgomery
Alaska
Anchorage
Arizona
Phoenix
Tucson
Arkansas
Fayetteville
Little Rock
California
Los Angeles
Oakland
Orange County
Sacramento
San Diego
San Francisco
San Jose
Colorado
Boulder
Colorado Springs
Denver
Connecticut
Hartford
DC
Washington
Florida
Fort Lauderdale
Jacksonville
Miami
Orlando
Tampa
Georgia
Atlanta
Augusta
Savannah
Hawaii
Honolulu
Idaho
Boise
Illinois
Chicago
Indiana
Indianapolis
Iowa
Cedar Rapids
Des Moines
Kansas
Wichita
Kentucky
Lexington
Louisville
Louisiana
New Orleans
Maine
Portland
Maryland
Annapolis
Baltimore
Frederick
Hagerstown
Massachusetts
Boston
Cambridge
Springfield
Michigan
Ann Arbor
Detroit
Grand Rapids
Minnesota
Minneapolis
Saint Paul
Mississippi
Jackson
Missouri
Kansas City
St. Louis
Nebraska
Lincoln
Omaha
Nevada
Las Vegas
Reno
New Jersey
Princeton
New Mexico
Albuquerque
New York
Albany
Buffalo
New York City
White Plains
North Carolina
Charlotte
Durham
Raleigh
Ohio
Akron
Canton
Cincinnati
Cleveland
Columbus
Dayton
Oklahoma
Oklahoma City
Tulsa
Oregon
Portland
Pennsylvania
Philadelphia
Pittsburgh
Rhode Island
Providence
South Carolina
Charleston
Columbia
Greenville
Tennessee
Knoxville
Memphis
Nashville
Texas
Austin
Dallas
El Paso
Houston
San Antonio
Utah
Salt Lake City
Virginia
Alexandria
Arlington
Norfolk
Richmond
Washington
Seattle
Tacoma
West Virginia
Charleston
Wisconsin
Madison
Milwaukee
Alberta
Calgary
Edmonton
British Columbia
Vancouver
Manitoba
Winnipeg
Nova Scotia
Halifax
Ontario
Ottawa
Toronto
Quebec
Montreal
Puerto Rico
San Juan