Learn how to render list and form components efficiently in React, and learn how to lift a shared state up when several components need the updated data.
Learning Objectives
- Render and transform lists with keys in React.
- Distinguish between controlled and uncontrolled React components.
- Create a controlled form component in React.
- Share component state by lifting state up to the closest common ancestor
- Share global state using React Context
- Course Introduction
- Rendering Lists in React
- Video: Transforming lists in JavaScript
- Video: Render a simple list component
- Lab: Exercise: Create a basic List component
- Reading: Solution: Create a basic List component
- Practice Quiz: Self-review: Create a basic List component
- Video: What are Keys in React?
- Video: Using Keys Within List Components
- Using Keys Within List Components in React
- Practice Quiz: Knowledge check: Rendering Lists in React
- Reading: Additional resources
- Forms in React
- Video: What are controlled components?
- Reading: Controlled components vs. Uncontrolled components
- Video: Creating a Form component in React
- Video: Create a Controlled Form Component
- Lab: Exercise: Create a registration form
- Reading: Solution: Create a registration form
- Practice Quiz: Self-review: Create a registration form
- Practice Quiz: Knowledge check: Forms in React
- Reading: Additional resources
- React Context
- Video: What you know about Props and State
- Video: What is Context, and why is it used?
- Lab: Exercise: Create a light-dark theme switcher
- Reading: Solution: Create a light-dark theme switcher
- Practice Quiz: Self-review: Create a light-dark theme switcher
- Reading: How re-rendering works with Context
- Practice Quiz: Knowledge check: React Context
- Video: Module summary: Components
- Quiz: Module quiz: Components
- Reading: Additional resources
Course Introduction
Video: Introduction to the course
This course is an advanced React course that builds on the concepts learned in the React Basics course. It covers topics such as:
- Rendering and transforming lists in React
- Working with forms
- Controlled components
- React Context
- Hooks
- JSX
- Component composition
- Higher-order components
- Render props
- Performance
- Testing and debugging
- Writing integration tests using the React testing library
The course also includes a lab project where you will code your own portfolio app.
Here are some of the key skills you will learn in this course:
- How to render and transform lists in React
- How to work with forms
- How to create controlled components
- How to use React Context
- How to use hooks
- How to use JSX
- How to compose components
- How to create higher-order components
- How to use render props
- How to improve the performance of your React apps
- How to test and debug your React apps
I hope you are excited to learn more about React in this advanced course!
Here are some additional details about the topics covered in the course:
- Rendering and transforming lists in React: This topic covers how to use the
map()
method to render and transform lists of components. You will also learn about the importance of using keys to uniquely identify elements in a list. - Working with forms: This topic covers how to create and handle forms in React. You will learn about the difference between controlled and uncontrolled components, and how to use React Context to share state between multiple form components.
- Controlled components: Controlled components are components that use a
value
prop to bind the input value to a variable in the component. This is the recommended way to handle form input in React, as it provides more control over the input value. - React Context: React Context is a way to share global state between components. This is a good way to share state between components that are not related to each other.
- Hooks: Hooks are a new feature in React that allow you to use state and other React features without writing a class component. This makes your code more concise and easier to read.
- JSX: JSX is a syntax extension that allows you to write React components in JavaScript. This makes it easier to write React code that looks like HTML.
- Component composition: Component composition is the process of combining multiple components to create a new component. This is a powerful way to reuse code and create complex UIs.
- Higher-order components: Higher-order components are functions that take a component as an input and return a new component. This is a powerful way to add functionality to components without modifying the original component.
- Render props: Render props are a way to pass a function to a component as a prop. This function is then called by the component to render its children. This is a powerful way to customize the rendering of a component.
- Performance: React apps can be made more performant by using techniques such as memoization and lazy loading.
- Testing and debugging: It is important to test and debug your React apps to ensure that they work correctly. This can be done using tools such as Jest and React Developer Tools.
Hello and welcome to this
advanced React course that continues from the
React basics course in this specialization. Throughout this
course, you’ll learn more advanced React concepts. Let’s take a moment
to review some of the key concepts and
skills that you’ll learn. In the first module, you’ll start by learning
how to render and transform lists in React and
work with forms. In this process, you will be introduced to the map method to perform transformation
operations and rendered lists of components. Then, you’ll learn about
identifiers called keys, which are an integral component, enlists transformation in React. You’ll dive into
controlled components with a focus on creating a controlled form
component in React and implementing your
own feedback form. You will revise what you
know about props and state. Exploring React Context as a viable alternative to local state in
certain situations. You can also look forward to working with practical
examples using the Context Application
Programming Interface or API to manage global
state in your React apps. In module two, you will gain an in-depth
understanding of hooks. This includes learning the use and purpose of React hooks, the rules for using
hooks in React, and how to build
custom hooks in React. For example, you will learn about the purpose
of the useState, useEffect, and useReducer
hooks and how to use them. In the third module, you’ll be introduced
to a variety of more advanced concepts related
to JSX as used in React, such as components and elements. You’ll explore the types
of children within JSX, discovering the importance of component composition
and the children prop, how to manipulate
children in JSX, and the spread
operator in React. You will also be introduced
to the process and purpose of creating higher-order
components and render props. Starting with an introduction
to crosscutting concerns. Another important
topic that will be covered is performance
in your React apps, as well as testing and
debugging your application. Plus, you’ll learn about writing integration tests using the
React testing library with a focus on testing
the behavior of forums and exploring practical
applications of tests. During these modules,
you’ll work through practical examples of
theoretical concepts based on a restaurant called
Little lemon and encounter activities to test
your knowledge and skills. In the last module, you’ll have the opportunity to demonstrate some of
your learning and your practical advanced
React skill set in a lab project where you code
your own portfolio app. You will also demonstrate
your knowledge of these topics in a
graded assessment. Well, I hope you’re
as excited as I’m to work through this
React advanced course. Let’s get started.
Video: React and your career opportunities
React is a popular JavaScript framework for building user interfaces. It is used by many large companies, including Meta, Netflix, and Airbnb. React is known for its simplicity, performance, and scalability.
Murtadha is a software engineer at Meta who has used React to build many of the company’s products. He says that React makes building web applications much easier and less error-prone.
React is used to create components, which are reusable pieces of code that can be used to build complex user interfaces. Components can be written in JavaScript, and there are different flavors of JavaScript that can be used with React.
In addition to web applications, React can also be used to build mobile and VR applications. React is a versatile framework that can be used to build a wide variety of applications.
Murtadha’s advice to anyone learning React is to stay consistent and not give up. It may seem complicated at first, but it will become easier with practice. React is a valuable skill to have, and it will make you more marketable to employers.
Here are some additional details about React:
- React is a declarative framework, which means that you describe what you want the UI to look like, rather than how to render it. This makes React code more concise and easier to read.
- React is highly performant, making it a good choice for building high-traffic applications.
- React is scalable, making it a good choice for building large and complex applications.
- React is versatile, making it a good choice for building a wide variety of applications.
If you are interested in learning React, there are many resources available online. You can also find many tutorials and courses on YouTube.
The keyword React is
more popular than words like orange juice and
renewable energy. It has been a framework that is very widely popular
and it’s something that a lot of jobs now require when they’re hiring
new engineers. My name is Murtadha.
I’m a software engineer at Meta based in Seattle office. Just about everything
I’ve built in my career at Meta has
been built in React. If you’re using any
of the Meta products, whether you’re using
Facebook or Instagram, most likely the buttons in the menus and the clicks
that you’re making are all events and components handled by via React framework. My career at Meta, has been developing
these components. Whether you’re using
it when a web, if you’re going and
posting a photo or if you’re making a comment, all of those interactions are powered by React components
behind the scene. Well, I think personally when
I first discovered React, I was like, “Oh, my God, this is so cool,”
and it just made building web applications
so much easier. It really simplified my
job as an engineer to write using this framework
and it’s very intuitive, it’s much less error-prone. If we look at the
trends we see in 2018, React actually rose up and exceeded what previously was the most popular web framework, which was known as jQuery, and React became the
most search keyword. It makes sense for it
to replace some of these older frameworks
that are not keeping up with the
speed of the industry. The main language
that’s used to create React components
it’s JavaScript, and there are actually
different flavors of JavaScript that can
be used with React. At Meta, we use a flow
flavor of JavaScript, and that allows us to
ensure type safety through the use of
developing React components. But there are other ways that React components can be built. Perhaps a popular way that is common in the industry
is using TypeScript. Besides these different ways to use React components on web, you can actually use
React to develop mobile components
on Android and iOS. Most recently, React
is releasing a way for developing VR components
like virtual reality, where people can use these same frameworks
consistently that are used in web and mobile to develop virtual
reality applications. The idea is to
simplify it and allow developers to create complex virtual
reality applications, but leverage the simplicity
and friendliness of React. That’s what has given
the motivation to create these different
frameworks of React across different segments
of the industry. At this point, it’s an
integral skill that just about every job and every application you build
will probably require. Having this knowledge will really help you through your
career and it’s going to also make your life easier to learn how to
use such framework. My advice to you as you
venture into this world of React is to stay consistent. It may at first seem a little complicated or overwhelming or some things may not make sense, but just power through it,
it will make your life a lot easier to learn
these principles. They’ll make you
much more attractive to employers in the future. Your ability to produce scalable web applications will be much better with the
use of this framework. Keep going and don’t let some of these confusing parts
of React slow you down.
Introduction
React is a popular JavaScript framework for building user interfaces. It is used by many large companies, including Meta, Netflix, and Airbnb. React is known for its simplicity, performance, and scalability.
If you are a JavaScript developer, learning React can open up many career opportunities. There are many jobs available for React developers, and the demand for React skills is only growing.
In this tutorial, we will discuss the benefits of learning React and the career opportunities that are available to React developers. We will also provide some tips for getting started with React.
Benefits of Learning React
There are many benefits to learning React. Here are a few of the most important benefits:
- High demand: There is a high demand for React developers. Many companies are looking for React developers to build their user interfaces.
- Simplicity: React is a relatively simple framework to learn. This makes it a good choice for beginners and experienced developers alike.
- Performance: React is a highly performant framework. This makes it a good choice for building high-traffic applications.
- Scalability: React is a scalable framework. This makes it a good choice for building large and complex applications.
- Versatile: React is a versatile framework. It can be used to build a wide variety of applications, including web applications, mobile applications, and VR applications.
Career Opportunities for React Developers
There are many career opportunities available for React developers. Here are a few of the most common career paths for React developers:
- Front-end developer: Front-end developers are responsible for building the user interfaces of web applications. React is a popular choice for front-end development, as it is a simple and performant framework.
- Full-stack developer: Full-stack developers are responsible for building the entire stack of a web application, including the front-end, back-end, and database. React is a good choice for full-stack developers, as it can be used to build both the front-end and back-end of an application.
- Mobile developer: Mobile developers are responsible for building mobile applications. React Native is a framework that allows you to build mobile applications using React.
- VR developer: VR developers are responsible for building virtual reality applications. React can be used to build VR applications, as it is a versatile framework that can be used to build a wide variety of applications.
Tips for Getting Started with React
If you are interested in learning React, here are a few tips to help you get started:
- Start with the basics: There are many resources available online that can teach you the basics of React. Once you have a good understanding of the basics, you can start building your own React projects.
- Find a mentor: A mentor can help you learn React and troubleshoot any problems you encounter. There are many React mentors available online.
- Join a community: There are many React communities online where you can ask questions and get help from other React developers.
- Attend conferences: There are many React conferences held throughout the year. Attending a conference is a great way to learn about the latest React news and trends.
Conclusion
Learning React can open up many career opportunities for you. If you are a JavaScript developer, I encourage you to learn React. It is a simple, performant, and versatile framework that can be used to build a wide variety of applications.
Reading: Course syllabus
Reading
By the end of this reading, you will have learned about the scope of things you will cover in this course.
Prerequisites
To take this course, you should understand the basics of React, HTML, CSS, and JavaScript. Additionally, it always helps to have a can-do attitude!
Course content
This course covers advanced React development. You’ll learn how to use more advanced React concepts and features, optimize and test your React applications, and become proficient in using React and JSX.
This course consists of four modules. They cover the following topics:
Module 1: Components
In this introductory module, you’ll learn about React and your career opportunities. You’ll also learn how to set up your coding environment so that you have as productive a learning experience as possible. The purpose of this module is to understand the what and the why behind learning React. You’ll also learn about career opportunities and how to set up your coding environment for the most efficient and productive learning experience.
In React, everything revolves around components. You’ll learn how to efficiently render list and form components, as well as how to lift up a shared state when several components need access to the data.
By the end of this module you will be able to:
- Outline React and various career opportunities.
- Render and transform lists with keys in React.
- Distinguish between controlled and uncontrolled React components.
- Create a controlled form component in React.
- Share component state by lifting state up to the closest common ancestor.
- Share global state using React Context.
Module 2: React Hooks and Custom Hooks
The second module of this course covers React hooks and custom hooks. You’ll learn how to use all the common hooks in React, and how to put them to use within your application. You will also test your skills by building your own custom hooks.
By the end of this module you will be able to:
- Explain the uses and purpose of React hooks.
- Detail the concept and nature of state and state change.
- Use the State hook to declare, read and update the state of a component.
- Use the Effect hook to perform side-effects within a React component.
- Use hooks to fetch data in React.
- Create appropriate custom hooks in React.
Module 3: JSX and Testing
In this module, you’ll learn about JSX and testing in React. You’ll cover JSX in-depth and discover advanced patterns to encapsulate common behavior via Higher-order components and Render Props. You will then learn how to use Jest and the React Testing Library to write and perform tests on your applications.
By the end of this module, you will be able to:
- Define the types of children within JSX.
- Describe the process and purpose of creating render props.
- Describe the process and purpose of creating higher-order components.
- Use Jest and the React Testing Library to write and perform tests on your applications.
Module 4: Graded Assessment
In this module, you will be assessed on the key skills covered in the course and create a project to add to your portfolio.
You will be provided with code snippets, and your task will be to use these, plus any of your own code to complete your developers’ portfolio.
This is a creative project, and the goal is to use as many React concepts as possible within this portfolio. You can use component composition, code reusability, hooks, manage state, interact with an external API, create forms, lists and so on.
By the end of this module, you will be able to:
- Synthesize the skills from this course to create a portfolio.
- Reflect on this course’s content and on the learning path that lies ahead.
Video: Grid layouts
- Benedict Hobart is a frontend engineer at Meta.
- He talks about CSS grids, a CSS layout spec that allows you to lay items out in a grid.
- CSS grids are a powerful tool that can be used to create responsive and flexible layouts.
- CSS grids can be used to solve a wide range of layout problems, including:
- Laying out images and text in a grid
- Creating responsive layouts that adapt to different screen sizes
- Building complex layouts with multiple columns and rows
- CSS grids are easy to learn and use, and they can be used in conjunction with other layout techniques, such as flexbox.
- Benedict encourages developers to learn how to use CSS grids to build more powerful and flexible web applications.
Here are some additional details about CSS grids:
- CSS grids are a relatively new layout spec, but they have quickly become popular due to their flexibility and power.
- CSS grids are based on the concept of rows and columns. You can define the number of rows and columns in your grid, as well as the size and alignment of each row and column.
- CSS grids are responsive, meaning that they will automatically adapt to different screen sizes. This makes them ideal for building mobile-friendly websites and applications.
- CSS grids are easy to learn and use. There are many resources available online to help you get started with CSS grids.
You need to lay things out. That’s very difficult
if you don’t have CSS grids, take one and. I’m having fun now. I’m Benedict Hobart. I’m a frontend engineer at Meta. Bootstrap is a very
popular CSS framework. CSS library used to help
quickly build websites. It has a lot of primitives
that you’ll commonly need when styling buttons or styling rows
or styling grids. Then there’s grids, which
is a CSS layout spec that allows you to lay
items out in a grid, which was previously a
very complicated task. I know it sounds simple,
but you can say, I want this item to
be at this part of the grid and in this
row and this row, and helps you make more
responsive apps as well. I learned about it years ago, I think probably
in 2017 or 2016. There is a whole class of layouts that are much more
easily solved by grids. Then by previous
layout approaches, you need to do a lot of
computation in JavaScript to know the widths and heights of
images and where to put them and how to get them
to lay out at the screen. But if you’ve got CSS grids,
it’s just one line of code to then get things to lay out in a performant way that’s
responsive and reliable. Generally, you put a bunch
of different layouts together when you’re
building a website. You might use a grid spec
in one spot, say in a table based layout that you
want to be responsive. But then you might use
another layout that contains a grid and wraps it. It’s important to
learn how to lay out items so you can build an app and define its
layout in a flexible way. Being able to say, I want this to appear at the bottom
of the screen when it’s a photo or appear as a tab
bar at the top of the screen. I think there’s a number of reasons you want to
learn how to do it. I think most websites can
be reduced to a grid. Knowing one layout and how one layout works
in detail allows you to take that knowledge to easily learn future layouts that
you might want to build. Starting off with one, getting
a good grasp of that is a really good
foundation to let you learn other layout and engines. If you ever want to move beyond
web into iOS and Android, they’ve probably got
their own layout engines that they use. I hope you develop a good
understanding of how to use grids in your app and
how it can be useful. I hope you understand
that it’s just one thing in a broader set of layout specs that you
can use in the browser. I guess more importantly, I hope you develop
a strong foundation here that you can take
into your grid career and learn other layout specs and how to build the
next generation of apps.
Introduction
A grid layout is a way of organizing elements on a page in a rectangular grid. This can be useful for creating layouts that are both visually appealing and functional. Grid layouts can be used to create a variety of layouts, including:
- A two-column layout with a sidebar and main content area
- A three-column layout with a header, main content area, and footer
- A grid of images or text
- A complex layout with multiple columns and rows
Benefits of using grid layouts
There are several benefits to using grid layouts:
- Flexibility: Grid layouts are very flexible and can be used to create a variety of layouts.
- Responsiveness: Grid layouts are responsive, meaning that they will automatically adapt to different screen sizes. This makes them ideal for building mobile-friendly websites and applications.
- Simplicity: Grid layouts are relatively simple to learn and use.
- Accessibility: Grid layouts can be made accessible to users with disabilities by using semantic HTML elements and CSS.
How to create a grid layout
To create a grid layout, you will need to use the grid
property in CSS. The grid
property allows you to define the number of rows and columns in your grid, as well as the size and alignment of each row and column.
Here is an example of how to create a two-column grid layout:
CSS
.container {
display: grid;
grid-template-columns: 1fr 1fr;
}
This code will create a grid with two columns of equal width.
You can also use the grid-template-rows
property to define the number of rows in your grid. For example, the following code will create a grid with three rows:
CSS
.container {
display: grid;
grid-template-rows: 1fr 1fr 1fr;
}
You can also use the grid-template-areas
property to define the specific areas of your grid. For example, the following code will create a grid with two columns and three rows, and will assign the first column and first row to the header
area, the second column and first row to the main
area, and the second column and second row to the footer
area:
CSS
.container {
display: grid;
grid-template-areas:
"header header"
"main main"
"footer footer";
}
Conclusion
Grid layouts are a powerful tool that can be used to create a variety of layouts. They are flexible, responsive, and easy to learn and use. If you are looking for a way to organize the elements on your page in a visually appealing and functional way, then grid layouts are a great option.
Rendering Lists in React
Video: Transforming lists in JavaScript
- The map method in JavaScript is used to transform lists of data.
- The map method takes a function as an argument and applies that function to each element in the array.
- The function that is passed to the map method can be used to transform the data in any way that you want.
- In the example in the video, the map method is used to transform a list of desserts into a new list that only contains the title, description, and price of each dessert.
- The map method is a powerful tool that can be used to manipulate data in JavaScript.
Here are some additional points that are mentioned in the video:
- The map method always returns a new array.
- The map method can be used to transform data of any type.
- The map method is often used to handle data that is fetched from an external provider.
- The map method is a simple but powerful tool that can be used to make your code more efficient and readable.
How many times have you found
yourself browsing apps? Maybe you’ve used an
app to order food, scrolling through
different menus hoping to find what you’d like. Well, lists like this are
common to almost every app, which is why it’s
important that you know how to manipulate
them in JavaScript. Chances are you’ll
need to transform various elements
before displaying the final list to your users. In this video, you’ll
learn how to use the map method in JavaScript
to transform lists of data. Let’s imagine that a
restaurant called Little Lemon would like to display a list
of its popular desserts. Remember that a list is a simple collection
of elements which, translated to JavaScript
terms, represents an array. These arrays can contain
any type of data. But the most common
type you’ll encounter per element is an object. Now, say Little Lemon uses
an external service to query a list of its most
requested desserts by users. However, when fetching data
from a third party like this, you are generally provided
with more data than you need. The data will be
provided in a format or shape that is determined
by the third party. This means that you may need
to write more code to handle the data in order to retrieve just the information you need. That’s where the
map method comes in as a way to ignore
everything that you do not want displayed on screen and extract only the data that
your users care about. Let’s explore how to
transform this list of dessert items using the
map method in JavaScript. In JavaScript,
when you deal with lists of items of any kind, you need to use the array type. JavaScript offers different
methods that you can use with arrays to perform
various operations. In order to perform a
transformation operation, you must use the map method. Coming back to Little Lemon, imagine you have a list
of its top requested desserts encompassed in
a variable called data. Each dessert has the
following properties: id, title, image,
description, and price. In this case, you
would like to show a very simple list of desserts with a property
called content, which you can create by
merging together the title and description and the price
of the delicious dish. First, I’m going to
define a new variable since the map method always
returns a new array. Let’s call this new
array top desserts. Next, I’m going to apply the map method to the
original data array. For now, I’ll return
the data as it is. You can examine the
basic structure of a map transformation. I would like the new items
to have two properties. The first is content, which is going to
be a combination of title and description. Let’s use a dash character
to separate the two. Secondly, there’s the price
which I will pass as it is. Last, I will console log the results to demonstrate
that the new list I have created
contains the shape or format that I
originally intended, and here’s your
transformed list. You just learned
how to transform data in JavaScript
with a map method. This is a simple yet powerful
tool you will find yourself using quite often when dealing with data from an
external provider. Your users will thank you when they experience
how easy it is to navigate and consume
information in your apps.
Introduction
Lists are a common data structure in JavaScript. They can be used to store a collection of data, such as numbers, strings, or objects. Lists can be manipulated in a variety of ways, including adding, removing, and sorting elements.
One way to manipulate lists is to transform them. Transformation is the process of changing the data in a list in some way. For example, you could transform a list of numbers to a list of strings, or you could transform a list of objects to a list of their property values.
The map method
The map()
method is a JavaScript method that can be used to transform lists. The map()
method takes a function as an argument and applies that function to each element in the array. The function that is passed to the map()
method can be used to transform the data in any way that you want.
The following code shows how to use the map()
method to transform a list of numbers to a list of strings:
JavaScript
const numbers = [1, 2, 3, 4, 5];
const strings = numbers.map(number => number.toString());
console.log(strings); // ["1", "2", "3", "4", "5"]
In this code, the map()
method is used to transform the list of numbers to a list of strings. The function that is passed to the map()
method takes a number as an argument and returns the string representation of that number.
The filter method
The filter()
method is another JavaScript method that can be used to transform lists. The filter()
method takes a function as an argument and returns a new array that contains only the elements in the original array that satisfy the function.
The following code shows how to use the filter()
method to transform a list of numbers to a list of even numbers:
JavaScript
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(number => number % 2 === 0);
console.log(evenNumbers); // [2, 4]
In this code, the filter()
method is used to transform the list of numbers to a list of even numbers. The function that is passed to the filter()
method takes a number as an argument and returns true
if the number is even and false
otherwise.
The reduce method
The reduce()
method is a JavaScript method that can be used to transform lists into a single value. The reduce()
method takes a function as an argument and applies that function to each element in the array, starting with the first element and moving to the last element. The function that is passed to the reduce()
method can be used to combine the elements in the array into a single value.
The following code shows how to use the reduce()
method to calculate the sum of a list of numbers:
JavaScript
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // 15
In this code, the reduce()
method is used to calculate the sum of the numbers in the numbers
array. The function that is passed to the reduce()
method takes two arguments: the accumulator and the current value. The accumulator is the running total of the sum, and the current value is the current element in the array. The function returns the new accumulator value.
Conclusion
These are just a few ways to transform lists in JavaScript. There are many other ways to transform lists, and the best way to transform a list will depend on the specific task that you are trying to accomplish.
Which of the following is true about the map() method in JavaScript. Select all that apply.
The map() method is a transformation operation.
That’s correct. The map() method in JavaScript is used to transform lists of data.
The map() method is useful for handling third party data.
That’s correct. Using the map() method in JavaScript to display data fetched from a third party or external provider differently in your app is a common use case of the map() method.
The map() method returns a new array.
That’s correct. When using the map() method, you will need to define a new variable, as it always returns a new array.
Video: Render a simple list component
This video shows how to display a collection of elements with React by using the map function in JSX syntax. The example uses the list of little lemons’ best desserts to display a simpler version of the collection by displaying just the title and price.
The first step is to create a new variable called listItems to store the result of the transformation. Then, a loop is used to iterate through the array of desserts using the JavaScript map function. Inside the map function, a React component is returned as the transformation applied to each element. This allows the results to be embedded directly into the return JSX.
To display the title of the dessert and its price, a new variable called itemText is created. This variable uses a dash to separate the title and price, and the dot notation to access the needed properties from the dessert object.
The last step is to embed the listItems variable into the HTML list wrapper component, unordered list or UL. This will display the desserts in a simple and concise way.
This technique can be used to display any collection of elements with React, making it a powerful tool for building user interfaces.
Did you know that with React, you can transform
any list of items into a collection of
React components? Drawing upon the
previous example of little lemons
list of deserts, imagine the restaurant
would like to go one step further by providing
its online visitors with a sneak peek at
the best desserts in a dedicated section to
encourage them to order. In this video, you
will learn how to display a collection
of elements like this with React by using the
map function in JSX syntax. Recall that JSX is a
special syntax extension to JavaScript that React uses to describe user
interfaces or UIs, and that a component is a
function that returns JSX. Now, let’s explore how to render a list of
elements with React. In this demonstration,
I will use the list of little lemons
best desserts again, each one having the
following properties, ID, title, image,
description, and price. The aim is to display a simpler version of
this collection of top desserts by displaying
just the title and the price. The first step is to create
a new variable called list items to store the result of the transformation
I’m going to perform. For that, I’m going to
loop through the array of deserts using the
JavaScript math function. You may be wondering
what it should return inside the map function. Traditionally in JavaScript, you would return any datatype. When you are working
with lists in JSX, you can also return
a React component as the transformation
applied to each element. You will discover how
that’s useful later on, since it will be able
to embed the results directly into the return JSX. Recall also that all HTML tags
are components by default. You can leverage all
the semantic tags you already know from HTML. For list items,
your best choice is the list item or
LI semantic tag. I’m going to return an
empty list item for now. Because the goal is to display the title of the
desert and its price, I’m first going to
create a new variable for the text named item text. I will use a dash to
separate title and price, as well as the dot
notation to access the needed properties
from the desert object, which are title and price. Since this is a
JSX transformation that will be part of the render method of this component, you have to use curly braces to wrap your data, in this case, the text for each list item, which is the value of
our variable item text. The last step is to go to
the render method and embed list items into the HTML
list wrapper component, unordered list or
UL and that’s it. The deserts are displayed in
a simple and concise way. This addition will
certainly help little lemon
restaurants to increase its orders. Well done. You have learned
how to transform collections of
elements with React by using a combination of the map function in
JSX curly braces. With lists being one of the core building blocks
of app development, you’re now one step further in your journey to
creating great apps.
Tutorial: Render a simple list component in React
To render a simple list component in React, you can use the following steps:
- Create a new React component.
- In the render() method, return a list of list items.
- Each list item can be a simple string or a more complex component.
Here is an example of a simple list component in React:
JavaScript
import React from "react";
const ListComponent = () => {
return (
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
);
};
export default ListComponent;
This component will render a simple list with three list items: “Item 1”, “Item 2”, and “Item 3”.
You can also use the map() function to render a list of list items from an array of data. For example, the following component will render a list of the numbers from 1 to 10:
JavaScript
import React from "react";
const ListComponent = () => {
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
return (
<ul>
{numbers.map((number) => (
<li key={number}>{number}</li>
))}
</ul>
);
};
export default ListComponent;
This component will render a list with ten list items, each containing a number from 1 to 10.
You can use list components in a variety of ways to build user interfaces. For example, you could use a list component to display a list of products, a list of users, or a list of tasks.
Here are some additional tips for using list components in React:
- Use list components to organize your data in a logical way.
- Use list items to display individual pieces of data.
- Use the map() function to render a list of list items from an array of data.
- Use CSS to style your list components to match your overall design.
By following these tips, you can use list components to create user interfaces that are efficient, user-friendly, and visually appealing.
When you are working with lists in JSX, you can return a React component. What is the purpose of curly braces in this process?
To access the content of the variable that represents your list item.
That’s correct. When a JSX transformation will be part of the render method of components, you need to use curly braces to wrap your dynamic data so it can be accessed.
Lab: Exercise: Create a basic List component
Reading: Solution: Create a basic List component
Code
There are three types of operations you need to apply to the list of desserts: filtering, sorting and mapping.
Although the order of the operations is not that important, it’s recommended to leave the final projection (mapping) to the end, since that final projection may skip some of the data needed for the filtering and sorting criteria.
Filtering
The first requirement is to display desserts that have less than 500 calories. That means Cheesecake, which has 600 cal, should be omitted. When you need to eliminate elements from your lists based on a certain condition or set of conditions, you need to use the filter() method.
The filter method creates a copy of the array, filtered down to just the elements from the original array that pass the test. In order words, it will return a new list with just the elements that fulfil the condition.
Each dessert from the list has a property called calories, which is an integer representing the number of calories. Therefore, the condition to be implemented should be as follows:
const lowCaloriesDesserts = props.data
.filter((dessert) => {
return dessert.calories < 500;
})
lowCaloriesDessert variable will then hold a list of three desserts, without Cheesecake.
Sorting
The second requirement you have to implement is sorting the list by calories, from low to high or in ascending order. For that, arrays in JavaScript offer the sort() method, which sorts the elements of an array based on a comparison function provided. The return value from that comparison function determines how the sorting is performed:
compareFn(a, b) return value | sort order |
---|---|
> 0 | sort a after b |
< 0 | sort a before b |
=== 0 | keep original order of a and b |
You can chain one operation after another. Recall that filter returns the new array with the filtered down elements, so sort can be chained right after that, as below:
const lowCaloriesDesserts = props.data
.filter((dessert) => {
return dessert.calories < 500;
})
.sort((a, b) => {
return a.calories - b.calories;
})
The compare function makes sure the sorting occurs in ascending order, according to the table above.
Mapping
Finally, to apply the desired projection and display the information as requested, you can chain the map operator at the end and return a <li> item with the dessert name and its calories, both separated by a dash character, and the word “cal” at the end.
The final code should look like below:
const lowCaloriesDesserts = props.data
.filter((dessert) => {
return dessert.calories < 500;
})
.sort((a, b) => {
return a.calories - b.calories;
})
.map((dessert) => {
return (
<li>
{dessert.name} - {dessert.calories} cal
</li>
);
});
And the full implementation of the DessertsList component:
const DessertsList = (props) => {
const lowCaloriesDesserts = props.data
.filter((dessert) => {
return dessert.calories < 500;
})
.sort((a, b) => {
return a.calories - b.calories;
})
.map((dessert) => {
return (
<li>
{dessert.name} - {dessert.calories} cal
</li>
);
});
return <ul>{lowCaloriesDesserts}</ul>;
}
export default DessertsList;
Final result
This is what should be displayed in your browser:
Practice Quiz: Self-review: Create a basic List component
When using the filter operator from arrays in JavaScript, what type should you return from the predicate function to determine if the element should be filtered out or not?
You should return true to keep the element and false to filter out the element.
That’s correct, the predicate function should always return a boolean, being true to keep the item or false to remove it.
AI assistant
The answer is you should return true to keep the element and false to filter out the element.
The filter() method in JavaScript takes a predicate function as an argument. The predicate function is a function that takes an element of the array as its argument and returns a boolean value. The element will be included in the resulting array if the predicate function returns true, and it will be excluded if the predicate function returns false.
The type of the value returned from the predicate function must be a boolean value. This means that the predicate function must return either true
or false
. If the predicate function returns any other type of value, the filter() method will throw an error.
For example, the following predicate function returns true
if the element is an even number and false
if the element is an odd number:
JavaScript
function isEven(number) {
return number % 2 === 0;
}
Here is how we can use the filter()
method to filter an array of numbers to only include the even numbers:
JavaScript
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(isEven);
console.log(evenNumbers); // [2, 4]
The evenNumbers
array will contain the numbers 2 and 4, because they are the only even numbers in the numbers
array.
If we were to return null
or undefined
from the predicate function, the filter() method would throw an error.
I hope this helps!
When chaining the three array operators required to complete the exercise, map, filter and sort; in which order should they be applied to props.data?
Filter, sort, map.
That’s correct, filter should go before sort since it returns a new array, making sure a copy of props.data is created before doing the sorting, which is a mutative operation. Map should be always the last, to transform the item into the final React Element that should be rendered.
AI assistant
The correct order to chain the three array operators map
, filter
, and sort
is:
filter, sort, map
Let’s break it down step by step.
- Filter the array to only include desserts that are ice cream.
- Sort the array by name.
- Map the array to return a string with the dessert name and calories.
Here is an example of how we can do this in JavaScript:
JavaScript
const desserts = [
{
name: "Chocolate Ice Cream",
calories: 250,
},
{
name: "Vanilla Ice Cream",
calories: 200,
},
{
name: "Strawberry Ice Cream",
calories: 150,
},
];
const filteredDesserts = desserts.filter((dessert) => dessert.type === "ice cream");
const sortedDesserts = filteredDesserts.sort((a, b) => a.name.localeCompare(b.name));
const dessertsWithCalories = sortedDesserts.map((dessert) => `${dessert.name} (${dessert.calories} calories)`);
console.log(dessertsWithCalories); // ["Chocolate Ice Cream (250 calories)", "Vanilla Ice Cream (200 calories)", "Strawberry Ice Cream (150 calories)"]
The filteredDesserts
array will contain only the desserts that are ice cream. The sortedDesserts
array will contain the filteredDesserts
array sorted by name. The dessertsWithCalories
array will contain the sortedDesserts
array with each dessert name and calories concatenated together.
When using the map function to transform an array item into a
element, what of the following code snippets should be inside the
tag to render the list item correctly in the following format: Ice Cream – 200 cal
<li>{dessert.name} – {dessert.calories} cal</li>
That’s correct, you should always use curly braces {} to access dynamic data in JSX, without any extra dollar symbol $.
AI assistant
The correct code snippet to render the list item correctly in the following format: Ice Cream - 200 cal
is:
<li>{dessert.name} - {dessert.calories} cal</li>
The map
function in JavaScript takes a function as an argument and applies that function to each element of the array. The function that is passed to the map
function is called the mapper function. The mapper function takes an element of the array as its argument and returns a new value.
In this case, the mapper function is returning a string with the dessert name and calories concatenated together. The dessert.name
and dessert.calories
variables are properties of the dessert object.
The { }
syntax is used to create a template literal. A template literal is a string that can contain expressions. In this case, the expression dessert.name
is being evaluated and the result is being inserted into the string.
The -
character is used to concatenate the two strings together.
The cal
string is being appended to the end of the string.
I hope this helps!
Video: What are Keys in React?
- React is a JavaScript library that is used to build user interfaces. It is known for its performance and its ability to automatically optimize updates in the UI.
- Keys are a special attribute that can be used with lists of elements in React. They help React to identify which elements have changed, been added, or removed.
- When keys are used correctly, they can improve the performance of React apps. However, if they are used incorrectly, they can have the opposite effect.
- The best way to choose a key for a list element is to use a unique identifier that is guaranteed to be unique among its siblings. This could be a unique ID from your data, or it could be a generated ID.
- You should avoid using the index of an element as a key, unless you are sure that the order of the elements will never change.
Here are some additional key points from the passage:
- React’s diffing algorithm is very efficient, but it can’t always make the optimal decisions when updating lists.
- Keys can help React make better decisions about how to update lists, which can improve performance.
- The wrong key can actually make performance worse, so it’s important to choose keys carefully.
One important advantage of
using React is its ability to automatically
optimize updates in your user interfaces or UIs. If React was a plane, it would use autopilot
mode in most cases, letting you relax in
the driver’s seat. But even with autopilot, you’ll need to take action
sometimes like for example, performing a specific
maneuver to land the plane. The same is true
for React as there are scenarios where
you as the developer, we need to take extra
steps to specify how React should behave
when your UI changes. In this video, you will
explore how to use keys as a way to do so when dealing
with lists of elements, you will learn how
to use keys to identify and distinguish
elements in a list, how to determine the right
key for your list items, as well as what using keys incorrectly means for
your app’s performance. Because React is
fast by default and designed with out-of-the-box
performance in mind, you usually don’t have to think about updates in your UIs. When computing a change, React applies it’s stiffening algorithm to calculate
the minimum number of changes that are
necessary to perform an update in your
tree of components. Although this algorithm
works perfectly most of the time, as
mentioned earlier, there are some cases
where React can’t make important assumptions to find the most optimal
path for an update, which means the developer
will need to step in. Let’s explore one such example. Imagine the drink section in the little lemon
online menu where restaurant managers can add new drinks depending
on the season. When they add a new element
at the end of the list, the different
algorithm works well, since React will match
the two beer trees, match the two wine trees, and then insert the cider tree. However, when inserting a new element at the
beginning of the list, the algorithm offers
worse performance because React will mutate every child instead
of realizing it can keep the beer and wine
sub trees intact. This inefficiency
can be a problem. To solve this issue, React supports a key
attribute. What are keys? Keys are identifier’s that
help React to determine which items have changed
or added or are removed. They also instruct how to treat a specific
element when an update occurs and whether
its internal state should be preserved or not. To illustrate, adding a key to the last example can make the
tree conversion efficient. That’s because react now
knows that the element with the key cider is the new one and the elements
with the keys, beer and wine have just moved. The general rule of thumb
with keys is to use a stable identifier that is
unique among its siblings. This allows React to reuse as many elements from
the list as possible, avoiding unnecessary
recreations, especially when their content is exactly the same and
the only thing that has changed is their
position in the list. The key used most often is a unique ID that
comes from your data. Those IDs typically
mirror a database ID, which has an ID
given to an item in a database that by nature
is guaranteed to be unique. But what happens in cases
where your data doesn’t have any suitable ID or
you are rendering a list that is not dependent
on any server data? In these scenarios,
you may think that generating your own
unique IDs is sufficient, whether you do so via an external library or with
a randomizer function, like the built-in
math.random function. However, why that approach will indeed avoid any
collisions in your keys, meaning that it will not produce two keys
that are the same, it will not preserve the internal state
of your list items. This is because when a
re-rendering occurs, those keys will be different, resulting in React having to recreate your list from scratch. As a last resort, you may use the item index. Since it determines the position of each element in the list, it guarantees the
absence of duplicates, but indexes are not
recommended for keys if the order of
items may change, for example, in cases
where your list has sorting capabilities or users can either add or remove items. When used incorrectly,
keys can negatively impact performance and may cause unexpected glitches in your
UI when updating your list. That’s why it is very
important to make a conscious decision about
your key’s implementation. You have now been
introduced to keys in React and how to use them when dealing with
lists of items, such as using keys to distinguish
between list elements, choosing the right key, and the effects of incorrect usage of keys
on app performance. A primary takeaway is
to always use a key that is guaranteed to be
unique among its siblings. Use unique IDs from your
data when possible. You can use indexes as a last resort but
don’t forget that this approach will not work when the order of your list
items is prone to change. Next up, you’ll have the
opportunity to explore using keys within list components
in practice. Bye for now.
What are keys in React?
Keys are a special attribute that can be used with lists of elements in React. They help React to identify which elements have changed, been added, or removed.
When keys are used correctly, they can improve the performance of React apps. However, if they are used incorrectly, they can have the opposite effect.
How to use keys in React
To use keys in React, you need to add the key
attribute to each element in the list. The value of the key
attribute should be a unique identifier for that element.
For example, if you have a list of users, you could use the user’s ID as the key.
const users = [
{ id: 1, name: "John Doe" },
{ id: 2, name: "Jane Doe" },
];
const App = () => {
return (
<ul>
{users.map((user, index) => (
<li key={user.id}>
{user.name}
</li>
))}
</ul>
);
};
The importance of keys
Keys are important because they help React to identify which elements have changed, been added, or removed. This is important because React uses a diffing algorithm to update the UI when the state of the app changes. The diffing algorithm compares the old and new state of the app, and only updates the elements that have changed.
If keys are not used, React will have to re-render the entire list, even if only one element has changed. This can be inefficient and can lead to performance problems.
Choosing the right key
The best way to choose a key for a list element is to use a unique identifier that is guaranteed to be unique among its siblings. This could be a unique ID from your data, or it could be a generated ID.
You should avoid using the index of an element as a key, unless you are sure that the order of the elements will never change.
Conclusion
Keys are a powerful tool that can help you improve the performance of your React apps. However, it’s important to use them correctly. By choosing the right keys and using them consistently, you can ensure that React is able to update your lists efficiently.
Which of the following statements about keys in React are true? Select all that apply.
- Keys help React determine which items have changed, are added or are removed.
- Keys instruct React about whether a specific element’s internal state should be preserved or not.
- Keys instruct React how to treat a specific element when an update occurs.
Video: Using Keys Within List Components
Summary:
This video teaches how to use keys correctly within list components and React.
A key is a unique identifier for each item in a list. It is used by React to track the identity of elements and update the UI efficiently.
When using indexes as keys, the order of the list items is prone to change. This can cause problems, such as the text inputs not moving when the order of the todos is reversed.
To fix this, you can use a unique identifier, such as the id property from the data model, as the key.
Conclusion:
By choosing the right keys in your React code, you can ensure that your lists are updated efficiently and that your users have a good experience.
In this video, you will learn how to use
keys correctly within list components and react through a practical example. Imagine that little lemon restaurant
managers would like a separate application that keeps record of
the tasks they need to do. In order to do that, I have built a very
simple todo list app with two different editable todos that
are represented via text inputs as well as a button that will
reverse the order of the todos. I will start by walking you through
the code example I created previously with Create React App. The todo component is basically
a table row which has an id, a text input to type a value and
a date of creation. Both id and createdAt are passed as props whereas the
input value state lives in the dom node. In other words, the text input
is an uncontrolled component. The main app component encompasses the
whole interface displayed on the screen. The todos data model is a piece of state
which is essentially an array of objects where each object contains an id and
a date of creation. Then there is the reverse order function
which effectively changes the order of the todo’s. The reverse method from arrays
is a mutated operation. That means that it modifies
the original array rather than a copy. To avoid mutating the react state which
is something you should never do, it’s important to make
a copy of the array first, which I’m doing by using
the ES6 spread operator. Finally, when it comes to the jsx for
the user interface, there is a wrapping div, a button to
reverse the order of the todos and a table where each table
row is a todo task. Each todo instance receives an id and createdAt as props which we
are passing from the data model. Now coming back to the app, the first thing I’m going to do
is to open the browser console. A warning in red is displayed. When you’re running your
application in development mode, React does a great job of providing
solutions to potential problems in your applications via contextual
warnings as console errors. The warning clearly states that each child
in the list should have a unique key prop and that I need to check the render
method of the app component. The index position of the todo item
fulfills the requirement that the React warning is asking about. So I’m going to use that. Okay, now when I reload the application,
the warning disappears. However, I haven’t tested
the application yet. So let’s type some todos and explore
what happens when I reverse the order. For the first one, I will type stock take
and for the second one, process payroll. Now I would like to reverse the order
because the managers should do payroll first. That didn’t work now, did it? The text inputs have not moved but
everything else has. Well, you have just discovered one of the
main problems when using indexes as keys when the order of your list
items is prone to change. So what exactly is happening? If I go back to the code and
take a look at the jsx for each todo, when I reverse the order of the todos,
the id and createdAt prop have changed. But the key is still the same
because I’m using the index. Since it’s the same, React is instructed
to keep the internal state of that node. That’s why the input state
from the todo is preserved. Now how do you fix that? Coming back to the key requirement,
it has to be something unique but that correctly identifies each todo, no
matter what its position is in the list. In this case, I can definitely use the id
property from the data model as my key. After all,
that is guaranteed to be unique per todo. So now I’m going to
implement that change and I will run the previous test again by
clicking the button one more time. Great, this time it worked as intended. You have learned about choosing
keys in your React code. You will come across collections
of elements quite frequently. And with your knowledge of keys,
allowing your users to do the tasks they want to complete first
won’t be a problem anymore.
Using Keys Within List Components in React
Keys are a unique identifier for each item in a list. They are used by React to track the identity of elements and update the UI efficiently.
When to use keys
You should use keys whenever you are rendering a list of elements in React. This is especially important if the order of the list items is prone to change.
How to choose a key
The key should be something unique that identifies each item in the list. It is often a good idea to use the ID of the item from your data model.
Example
Here is an example of how to use keys in a list component:
JavaScript
const App = () => {
const todos = [
{ id: 1, text: 'Stock take' },
{ id: 2, text: 'Process payroll' },
];
return (
<div>
<ul>
{todos.map((todo) => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
</div>
);
};
In this example, we are using the id
property of each todo item as the key. This ensures that each todo item has a unique identifier, even if the order of the list changes.
Benefits of using keys
Using keys has a number of benefits, including:
- Improved performance: React can update the UI more efficiently when it knows which items have changed and which items have stayed the same.
- Reduced bugs: Using keys can help to prevent bugs, such as text inputs not moving when the order of the list changes.
- Better developer experience: Using keys can make your code more readable and maintainable.
Conclusion
Using keys is an important part of developing React applications. By using keys correctly, you can improve the performance, reduce bugs, and create a better developer experience.
True or false: It is recommended to use item indexes as keys when selecting keys for rendered list items.
False
That’s correct. Although item indexes can be used as keys, using indexes as keys can create problems if the order of your list of items is prone to change and can negatively affect performance. Using unique and stable identifiers, such as item IDs, is recommended instead.
Practice Quiz: Knowledge check: Rendering Lists in React
Imagine you have an array with one object that represents a dessert. You would like to apply some transformation to the item to output a different structure using the map function as per the code below. What would be the value of the newDesserts variable?
const desserts = [
{
title: 'Chocolate Cake',
description: 'Chocolate cake is a cake flavored with melted chocolate',
calories: 500,
}
];
const newDesserts = desserts.map((dessert) => {
return {
title: dessert.title.toUpperCase(),
...dessert,
kCal: dessert.calories / 1000,
};
});
[
{
title: ‘Chocolate Cake’,
description: ‘Chocolate cake is a cake flavored with melted chocolate’,
calories: 500,
kCal: 0.5,
}
]
That’s correct, since the mapping output merges the previous object values after the title is re-defined, it has no effect and the title is still as before. Also, a new property is introduced, kCal.
How do you access dynamic data inside the JSX from the render function?
Wrapping the variable in question with curly braces.
That’s correct, that’s the way to access dynamic data in JSX.
AI assistant
All three of the options you listed are ways to access dynamic data inside the JSX from the render function.
- Using local state in the component: This is a good option if the data is only needed by the component itself and is not shared with other components. To use local state, you can declare a state variable in the component and then access it in the JSX using curly braces.
- Using component props: This is a good option if the data is needed by multiple components and is passed to the component from its parent. To use component props, you can access them in the JSX using curly braces.
- Wrapping the variable in question with curly braces: This is a good option if the data is global or is passed to the component as a function parameter. To wrap the variable in curly braces, simply place it inside of curly braces in the JSX.
Here is an example of how to use each of these methods:
Using local state:
JavaScript
class MyComponent extends React.Component {
state = {
data: 'This is some dynamic data.'
};
render() {
return (
<div>
<h1>{this.state.data}</h1>
</div>
);
}
}
Using component props:
JavaScript
const MyComponent = ({ data }) => {
return (
<div>
<h1>{data}</h1>
</div>
);
};
// Usage:
<MyComponent data="This is some dynamic data." />
Wrapping the variable in question with curly braces:
JavaScript
const MyComponent = () => {
const data = 'This is some dynamic data.';
return (
<div>
<h1>{data}</h1>
</div>
);
};
Which method you choose will depend on the specific needs of your application.
What could be a potential problem of using a randomiser function that generates an integer number from 0 to 10 as a key for your list items, having a list of only eight items? Select all that apply
The randomiser function does not entirely guarantee that the keys it generates will be different per item and a collision could happen, having two items with the same integer as keys.
That’s correct, since each value generated from the randomiser function is independent of the other, you could have key duplications.
There is no persistence of the keys generated since the moment the component re-renders the keys will vary and that could cause unexpected UI changes.
That’s correct, when a re-render occurs, the randomiser could generate a different value per list item and that could cause issues with the internal state of the component.
AI assistant
All three of the options you listed are potential problems of using a randomizer function that generates an integer number from 0 to 10 as a key for your list items, having a list of only eight items:
- The randomizer function does not entirely guarantee that the keys it generates will be different per item and a collision could happen, having two items with the same integer as keys.
This is because random number generators are not perfect. There is always a chance that two random numbers could be the same, even if the generator is using a good algorithm.
- There is no persistence of the keys generated since the moment the component re-renders the keys will vary and that could cause unexpected UI changes.
This is because random number generators typically generate different numbers each time they are called. This means that if you use a randomizer function to generate keys for your list items, the keys will change every time the component re-renders. This could cause unexpected UI changes, such as list items jumping around or disappearing.
- The randomizer function is a potential performance bottleneck since it has to run every re-render and it’s an unnecessary computation.
This is because random number generators are typically computationally expensive. If you use a randomizer function to generate keys for your list items, it will have to run every time the component re-renders. This could lead to performance problems, especially if you have a large list of items.
In general, it is not a good idea to use a randomizer function to generate keys for your list items. There are better options available, such as using the ID of each item in your data model.
Here is a recommendation for how to fix the problems you listed:
- Use a unique identifier for each item in your data model as the key. This is the best way to ensure that each item in your list has a unique key.
- If you do not have a unique identifier for each item in your data model, you can create one yourself. For example, you could use a UUID generator to create a unique identifier for each item.
- Avoid using randomizer functions to generate keys for your list items. This is not a reliable way to generate unique keys, and it could lead to performance problems.
The todos array contains a list of todo objects, where each object has an id property that is unique. Which of the following code snippets will throw a React warning when opening up the browser console? Select all that apply
{todos.map((todo, index) => (
<ToDo key=”myKey” id={todo.id} />
))}
That’s correct, the keys are all the same for all items and React will throw a warning in the console regarding that problem.
{todos.map((todo, index) => (
<ToDo id={todo.id} />
))}
That’s correct, since a key per list item is missing, React will throw a warning in the console.
AI assistant
The following code snippets will throw a React warning when opening up the browser console:
JavaScript
// 2. Using the index as the key
{todos.map((todo, index) => (
<ToDo key={index} id={todo.id} />
))}
JavaScript
// 3. Using a non-unique key for all list items
{todos.map((todo, index) => (
<ToDo key=”myKey” id={todo.id} />
))}
Explanation:
React uses keys to identify list items and efficiently update the UI. When you use the index as the key, the key will change if the order of the list items changes. This can cause unexpected behavior, such as list items jumping around or disappearing.
When you use a non-unique key for all list items, React will not be able to uniquely identify them. This can also lead to unexpected behavior.
How to fix the warnings:
To fix the warnings, you should use a unique key for each list item. The best way to do this is to use the ID of each item in your data model.
JavaScript
// 1. Use the ID of each item as the key
{todos.map((todo) => (
<ToDo key={todo.id} id={todo.id} />
))}
Conclusion:
It is important to use unique keys for list items in React to avoid unexpected behavior and improve performance.
What are the potential problems of using indexes as keys?
If the order of items may change, that can negatively impact performance and may cause issues with component state.
That’s correct, indexes are discouraged when the order of the items may change.
AI assistant
Yes, all of the potential problems you listed are correct. Here is a more detailed explanation of each problem:
- An index is not guaranteed to be unique. If you have two items in the same array with the same value, and you use the index as the key, React will not be able to uniquely identify them. This can lead to unexpected behavior, such as list items jumping around or disappearing.
- If the order of items may change, that can negatively impact performance and may cause issues with component state. When you use the index as the key, React has to recalculate the keys for all of the items in the list every time the order changes. This can be computationally expensive, and it can also lead to problems with component state, such as components not re-rendering correctly.
- The index is not persisted and will change the moment the component re-renders. This means that if you use the index as the key, and you have a stateful component that re-renders frequently, the keys for all of the items in the list will change frequently. This can lead to performance problems, and it can also make it difficult to debug your code.
How to avoid these problems:
The best way to avoid the problems listed above is to use a unique key for each list item. The best way to do this is to use the ID of each item in your data model. If you do not have a unique ID for each item in your data model, you can create one yourself, such as using a UUID generator.
Conclusion:
It is important to use unique keys for list items in React to avoid unexpected behavior, improve performance, and make your code more debuggable.
Reading: Additional resources
Reading
Here is a list of additional resources for Rendering Lists in React:
- Map() allows you to create new arrays populated with the results of calling a transformation function on every element.
- Rendering lists on official React docs website dives deeper into how to display multiple similar components from a collection of data, providing examples of both filtering and transformations.
- React keys on official docs offers a comprehensive set of memotecnic rules to reinforce how to use keys properly.
Forms in React
Video: What are controlled components?
Summary of the video on controlled components in React:
- Controlled components are React components that give you full control over the state of form elements.
- Instead of relying on the native state of DOM elements, controlled components use React state as the single source of truth for the displayed value of form elements.
- To create a controlled component, you need to use a combination of local state and the value prop.
- The value prop is a special property that React has added to most form elements to determine the input content at any point in time during the render life cycle.
- To get updates from any new text character entered in the input, you need to use the onChange callback.
- The onChange callback receives an event parameter, which is an event object representing the action that just took place.
- To get the new value from every keystroke, you need to access the target property from the event and grab the value from that object.
- To have control over the form values whenever the form is submitted, you can use the onSubmit prop in the form HTML element.
- The onSubmit callback also receives a DOM-like event as a parameter.
- To prevent the default HTML form behavior, you need to call event.preventDefault inside your onSubmit callback.
Example of a controlled component in React:
import React, { useState } from "react";
const ControlledInput = () => {
const [inputValue, setInputValue] = useState("");
const handleChange = (event) => {
setInputValue(event.target.value);
};
return (
<input
type="text"
value={inputValue}
onChange={handleChange}
/>
);
};
export default ControlledInput;
This example shows a controlled input component that uses React state to manage the value of the input field. The handleChange function is called whenever the user changes the value of the input field, and it updates the inputValue state variable accordingly. The value prop of the input field is set to the inputValue state variable, so that the input field always displays the current value of the state variable.
Benefits of using controlled components:
- Controlled components give you more control over the behavior of your forms.
- Controlled components make it easier to validate form data.
- Controlled components make it easier to implement custom form behavior.
Conclusion:
Controlled components are a powerful tool for creating forms in React. By using controlled components, you can have full control over the state of your form elements and implement custom form behavior.
When browsing the Internet, there’s a big chance that
you’ll land on a form, even without you realizing it. From simple email inputs and
subscribing to newsletters, to more complex forms such
as creating an account on your favorite social
media platform , forums are everywhere. You’ll probably find
yourself implementing them in your
applications regularly. In this video, you’ll
learn the concept of controlled components
in React and how they are used in
foreign processes. The fundamental
concepts of HTML forms and how forums can be
created as React components. When it comes to
React applications, HTML forms work differently
to other DOM elements. You may recall that the DOM is a logical tree-like structure representing the HTML document, and it uses nodes to describe the various
parts of the document. Traditional HTML forms
keep some internal state inside the DOM and have some default behavior
when submitting them. That’s normally done via
the action attribute, which points to the endpoint that will handle the request. But what if you
would like a more granular level of control? For example, customers of the little lemon
restaurant can reserve a table on the
website using a form. Imagine if there was a function that could
handle the submission of the form and access the data that the
user entered into it. That’s where controlled
components come in. Controlled components are a
set of components that offer a declarative application
programming interface or API to enable full
control of the state of form elements at any point
in time using React state. Rather than relying on the native state
from DOM elements, the React state is made the
single source of truth, controlling the
displayed value of your form elements at all times. The way you perform
this state delegation is via the value prop. Value is a special property, the React added to most of the
form elements to determine the input content
at any point in time during the
render life cycle. In order to create a
controlled component, you need to use a combination of local state and the value prop. Initially, you will assign the local stage to
the value property. But how do you get updates from any new text character
entered in the input? Well for that, you need a second prop to
complete the design of your controlled component,
the onChange callback. The onChange callback
receives an event parameter, which is an event object representing the
action that just took place similar to
events on DOM elements. To get the new value
from every keystroke, you need to access the
target property from the event and grab the value from that object,
which is a string. Finally, to have control over the form values whenever
the form is submitted, you can use the onSubmit prop
in the form HTML element. The onSubmit callback also receives a DOM-like
event as a parameter. There you can access your
form values to perform any desired logic that must
take place before submission, for example validating
your input values. Also, if you would
like to prevent the default HTML form behavior, you need to call
event.preventDefault inside your onSubmit callback. Well, there you have it. You have discovered a technique called controlled
components that enables react to be the source of truth for the state
of your form inputs. React offers controlled versions of the majority of input types and recommends using
controlled components for the implementation
of forums. However, keep in mind
that there’s still some form elements that remain uncontrolled similar to
their DOM counterparts. As you move forward
with your learning, you will gain more insight into both controlled and
uncontrolled form elements. In this video, you have
learned about the concept of controlled components
and React and how they are used in
foreign processes. You also explored the
fundamental concepts of HTML forms and how forms can be created as
React components.
What are controlled components in React?
Controlled components are React components that give you full control over the state of form elements. Instead of relying on the native state of DOM elements, controlled components use React state as the single source of truth for the displayed value of form elements.
How to create a controlled component
To create a controlled component, you need to use a combination of local state and the value
prop. The value
prop is a special property that React has added to most form elements to determine the input content at any point in time during the render life cycle.
For example, the following code shows a controlled input component:
JavaScript
import React, { useState } from "react";
const ControlledInput = () => {
const [inputValue, setInputValue] = useState("");
const handleChange = (event) => {
setInputValue(event.target.value);
};
return (
<input
type="text"
value={inputValue}
onChange={handleChange}
/>
);
};
export default ControlledInput;
This component uses the useState
hook to manage the state of the input field. The handleChange
function is called whenever the user changes the value of the input field, and it updates the inputValue
state variable accordingly. The value
prop of the input field is set to the inputValue
state variable, so that the input field always displays the current value of the state variable.
Benefits of using controlled components
There are several benefits to using controlled components:
- More control over form behavior: Controlled components give you more control over the behavior of your forms. For example, you can use controlled components to implement custom validation logic or to disable form elements based on the state of other form elements.
- Easier to validate form data: Controlled components make it easier to validate form data. For example, you can use controlled components to check if all required fields have been filled in or to check if the values of two fields match.
- Easier to implement custom form behavior: Controlled components make it easier to implement custom form behavior. For example, you can use controlled components to implement a custom autocomplete feature or to implement a form that automatically submits when all required fields have been filled in.
When to use controlled components
It is generally recommended to use controlled components for all form elements in React applications. This is because controlled components give you more control over the behavior of your forms and make it easier to validate form data and implement custom form behavior.
However, there are some cases where you may want to use uncontrolled components instead. For example, you may want to use an uncontrolled component if you need to access the DOM node of the form element or if you need to use the default HTML behavior of the form element.
Conclusion
Controlled components are a powerful tool for creating forms in React. By using controlled components, you can have full control over the state of your form elements and implement custom form behavior.
You are using controlled components in React in order to have more control over the forms in an application you are creating.
Which of the following props is used to perform state delegation?
value
That’s correct. State delegation is performed via the value prop. A combination of local state and the value prop is needed to create a controlled component.
Reading: Controlled components vs. Uncontrolled components
Video: Creating a Form component in React
A controlled component is a React component in which the form data is handled by the component’s state. This is in contrast to an uncontrolled component, in which the form data is handled by the DOM itself.
To create a controlled component in React, you need to:
- Create local state for the form inputs.
- Hook up the state to the form inputs using the
value
andonChange
props. - Use the
onSubmit
prop to control the submission of the form.
Some of the benefits of using controlled components include:
- You can prevent the default behavior of the form submit event.
- You can disable the Submit button when the form is not valid.
- You can easily clear out the form inputs after submission.
- You can perform validation on the form data before submitting it.
To make your controlled components more accessible, you can connect the labels with the inputs using the htmlFor
prop.
Conclusion:
Controlled components are a powerful way to create forms in React. They give you more control over the form data and behavior, which can lead to better user experiences.
Forms may look simple, but there are many
different features and functionality to forms. For developers, there is an
art to constructing forms. React makes constructing and customizing forms much
easier for developers, and that’s why it’s
such a popular choice. Would you like to master the art of building forms with react? Well, there are
some key concepts and features that you
will need to learn to truly unlock the versatility
and effectiveness of controlled components
and forms using React. The little lemon
restaurant online web page was created some time ago. While little lemon were happy with the results for some time, they started realizing
their users were having issues with
their old contact form. After receiving some advice, they concluded that
it needs to be rebuilt and they
have chosen React as the most suitable
framework for the task due to the ability to
easily apply the features, functionality, and control that they require from the form. In this video, you’ll learn
how to help little lemon by creating a
controlled component in React using local state and the onChange event to
update form inputs, avoiding the default
behavior of the form submit event and disabling
the Submit button when the form is not valid. Recall the controlled components
in React are those in which form data is handled
by the component’s state. Whereas uncontrolled
components are those in which the form data is
handled by the DOM itself. To gain more insight into creating form
components in React, you will now examine the code
of a basic form example. I am going to demonstrate the
creation of form components in React using an app I
constructed previously. In this example, the
project has been created with Create React app. The return method of this
functional component essentially has a form that
contains two elements, a text input to type a
username and a submit button. This form resembles a
classic HTML version, so it’ll work the same way, whether you’re
using React or not. To test the application, I type John as the name and
click on the Submit button. By doing so, the default
action of the form kicks in, which is a get request to
the root and a page refresh. In React, this current
implementation is considered an
uncontrolled form, having all the states
living in the DOM. Let’s work through the
necessary steps to transform this form into
a controlled version. First, I need to create some local state
for the text input, which I’m going to call name. Secondly, I need to
hook up that stage to my text input via two props, the value prop to
turn the input into a controlled one and onChange to receive all the changes per keystroke and thus update
the state of my input. Last, to control the
submission of the form, I have to use the onSubmit
prop in the form tag. For now, I’ll log
a basic message stating that the submission was successful to the console. Now, let’s check if the
form still works as before. I’ll type a name and click
Submit. And it’s working. My message was logged
to the console and the default behavior of
the form has continued on. Although this is great, I’d actually like to have more control on the
submission of the form. In particular, I’m not interested
in the default behavior of calling the root of the server and
refreshing the page. You may be wondering how I can prevent that from happening. In traditional forms, you will do this by returning false from the
onSubmit attribute. However, in React, the way to do it is by using the event property you
get as a parameter in the onSubmit callback and
calling prevent default on it. Now, when I submit
my form again, no refresh happens and no
server is hit with a request. Let’s go one step further and clear out the input
after submission. For that, I call the
state setter with an empty string inside
the onSubmit callback. Great. My form is taking shape. To demonstrate
even more benefits of controlled components, let’s perform an additional
improvement by only allowing the user to submit the form when the text input is not empty. Disabling the button is as easy as using the
disabled attribute. In this case, if name
is an empty string, this expression would
be evaluated as true and the button
would be disabled. So in the app, I can’t click on the button
if there’s no name provided. Finally, for best
accessibility practices, let’s connect the
label with the input. I set an ID for my input called name and now we will
connect the label. In traditional HTML forms, you would have to use
the for property. But in React, for is a reserved
word so you must use HTMLFor and pass the
ID of the input. Now, if I click on the label, its corresponding
input is focused. That’s it regarding the basics of controlled forums and react. You have learned how to transform an
uncontrolled form into a controlled version using local state and the
onChange event, as well as the onSubmit prop, and some of the
benefits of doing so. In terms of form submission, you also learned how to
avoid default behavior and disable the Submit button
when the form is invalid. Well done, you’re
making great progress.
To create a form component in React, you can follow these steps:
- Create a new React component file.
- Import the necessary React hooks, such as
useState
anduseEffect
. - Declare a state variable for each form input.
- Create a function to handle form submission.
- Render the form component, using the
value
andonChange
props to bind the state variables to the form inputs. - Use the
onSubmit
prop to handle form submission.
Here is an example of a simple form component in React:
JavaScript
import React, { useState } from 'react';
const Form = () => {
const [name, setName] = useState('');
const handleSubmit = (event) => {
event.preventDefault();
// TODO: Submit the form data to your backend server
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="name"
value={name}
onChange={(event) => setName(event.target.value)}
/>
<button type="submit">Submit</button>
</form>
);
};
export default Form;
This component uses the useState
hook to manage the state of the form input. The handleSubmit
function is called when the form is submitted. You can implement this function to submit the form data to your backend server.
To use this component, you can simply import it into your React app and render it like any other component:
JavaScript
import Form from './Form';
const App = () => {
return (
<div>
<Form />
</div>
);
};
export default App;
This will render a simple form with a text input and a submit button. When the user submits the form, the handleSubmit
function will be called.
You can customize this form component to meet your specific needs. For example, you can add additional form inputs, validation logic, and styling.
Here are some tips for creating form components in React:
- Use controlled components. This means that the component state should manage the values of the form inputs.
- Use validation to ensure that the form data is valid before submitting it.
- Use accessibility features to make your forms accessible to all users.
I hope this tutorial has helped you learn how to create form components in React.
Imagine you’d like to better control the submission of a form you’re creating for an app.
Which prop is required to prevent the default behavior of the form submit event in React?
preventDefault
That’s correct. To avoid the default form behavior of submitting in React, you must use the event property and call preventDefault.
Video: Create a Controlled Form Component
The tutorial on building a feedback form with React using controlled components and custom validation covers the following steps:
- Create a controlled component for the score using a range input.
- Add a text area for the comment.
- Implement validation to ensure that the comment is required when the score is equal to or lower than five, and that it should have at least 10 characters.
- Reset the form values after submission.
Here is a summary of the key points:
- Controlled components allow you to manage the state of form elements in React.
- You can use custom validation to ensure that user input meets certain requirements.
- It is a good practice to reset the form values after submission.
This tutorial provides a good foundation for building feedback forms with React. You can customize the form to meet your specific needs, such as adding additional fields or changing the validation rules.
Have you recently bought
a product through an ecommerce sites or maybe you booked a table at your
favorite restaurant? Well, if so, you may have received
a friendly email afterwards providing a link to a specific page to provide feedback
about the experience. This is an example
of a feedback form. Now that you’re familiar with controlled components in React, I’m going to
demonstrate how you can build this
functionality yourself. You will also be using
a range input and custom validation as part of
building a feedback form. Imagine little lemon, one of the best restaurants in town, would like to send their
customers a feedback form. Let’s go ahead and implement
a feedback form with React. Note that in this example, the project has been created
with Create React app. I’ve also added some
initial code that is a form with just a header
and a submit button. The requirements for
this example are an interface that allows
users to provide a score from 0-10 and then
additional comment to tell the chef how delicious the food they enjoyed a few days ago was. The first step is to implement
a control for the score. There are different
ways you can do this, but I’m going to go and choose a range input for this use case, as it provides the user
with a simple slider. To do this, let’s go ahead and create a new div to
wrap the component. This will consist of a label
that I will name score, as well as an input whose
type is going to be range. Range inputs offered
two prompts to define the range, min and max. For this example, I will set the minimum to 0 and
the maximum to 10. The application
is now displaying a user-friendly slider
to provide the score. To wrap up the range component, I need to do two more things. Turn the input into a
controlled components and visually show the numeric value that represents the
slider selection. For that, I will
define a new piece of state called score that I will initialize to 10 because I know the chef’s recipe is
usually unbeatable, enabling the user to
reduce the score down from 10 when they interact with the slider if they want to. Now in the range input, I have to use the value prop
to hook the state up and use onchange to receive the changes and update the
state accordingly. Since I also want
the numerical score to be displayed with a slider, I’m going to add
that information to the scored label
along with a star, so the user interface or
UI is clean and concise. Great, the feedback form
is starting to take shape. Now let’s implement the
second element from the form a widget to provide an
additional comment. Although I could use
a text input here, a comment could be very large. So a more suitable
choice is a text area. For that, I will declare another state variable
named comments that will be initialized
to an empty string. For the UI, I will create
a new div with a label and a text area component
for any additional feedback. Now that that is rendered well, I need to hook up the
state to the value prop and update the
changes via onchange. With that, the UI for the
feedback form is finished. The last thing I’d
like to implement is some validation to
ensure a comment is required when the score is equal to or lower than five, and that it should have
at least 10 characters. The chef receives
honest feedback from users that can be used
to improve his recipe. For that, I’m going to use the onsubmit callback
on the form component. I will call prevent
default first to avoid the default HTML form behavior
then I’m going to write an if statement to check if
the score is equal to or less than five and the comment has less
than 10 characters. If that’s the case, I will
show an alert to inform the user about the requirement and return from the function. Otherwise, the user is
good to go and I will log a message to confirm the successful submission
of the feedback. It’s also a good
practice to reset the form values
after submission. I’ll set both pieces of state to their initial values.
There you go. Everything is working well and the submission message is
logged into the console. You have learned how to build a feedback form with React using controlled components
and custom validation to make sure users have
a seamless experience.
To create a controlled form component in React, you need to:
- Define a state variable for each form field.
- Bind the state variables to the form fields using the
value
prop. - Handle changes to the form fields using the
onChange
event. - Update the state variables when the form fields change.
Here is a simple example of a controlled form component:
JavaScript
import React, { useState } from "react";
const Form = () => {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const handleSubmit = (event) => {
event.preventDefault();
// Submit the form data to your backend API
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
name="name"
placeholder="Enter your name"
value={name}
onChange={(event) => setName(event.target.value)}
/>
<input
type="email"
name="email"
placeholder="Enter your email"
value={email}
onChange={(event) => setEmail(event.target.value)}
/>
<button type="submit">Submit</button>
</form>
);
};
export default Form;
In this example, we are using the useState
hook to define two state variables, name
and email
. We are then binding these state variables to the name
and email
form fields using the value
prop.
When the user changes the value of either form field, the onChange
event is triggered. In the onChange
event handler, we update the corresponding state variable with the new value.
When the user clicks the submit button, the handleSubmit
function is called. In this function, we can submit the form data to our backend API.
You can use this same approach to create controlled form components for any type of form field, such as text inputs, select inputs, and checkboxes.
Here are some tips for creating controlled form components:
- Always bind the state variables to the form fields using the
value
prop. - Handle changes to the form fields using the
onChange
event. - Update the state variables when the form fields change.
- Validate the form data before submitting it.
- Reset the form values after submitting it.
Controlled form components are a powerful way to manage form data in React. They give you complete control over the state of the form and allow you to implement custom validation.
What are the two props you need to add when creating a controlled range component?
value and onChange
That’s correct. The value prop is used to hook the local state up and onChange prop is used to receive the changes and update the state accordingly
Lab: Exercise: Create a registration form
Reading: Solution: Create a registration form
Code
Here is the completed solution code for the App.js file:
import './App.css';
import {useState} from "react";
import {validateEmail} from "../src/utils";
const PasswordErrorMessage = () => {
return (
<p className="FieldError">Password should have at least 8 characters</p>
);
};
function App() {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState({
value: "",
isTouched: false,
});
const [role, setRole] = useState("role");
const getIsFormValid = () => {
return (
firstName &&
validateEmail(email) &&
password.value.length >= 8 &&
role !== "role"
);
};
const clearForm = () => {
setFirstName("");
setLastName("");
setEmail("");
setPassword({
value: "",
isTouched: false,
});
setRole("role");
};
const handleSubmit = (e) => {
e.preventDefault();
alert("Account created!");
clearForm();
};
return (
<div className="App">
<form onSubmit={handleSubmit}>
<fieldset>
<h2>Sign Up</h2>
<div className="Field">
<label>
First name <sup>*</sup>
</label>
<input
value={firstName}
onChange={(e) => {
setFirstName(e.target.value);
}}
placeholder="First name"
/>
</div>
<div className="Field">
<label>Last name</label>
<input
value={lastName}
onChange={(e) => {
setLastName(e.target.value);
}}
placeholder="Last name"
/>
</div>
<div className="Field">
<label>
Email address <sup>*</sup>
</label>
<input
value={email}
onChange={(e) => {
setEmail(e.target.value);
}}
placeholder="Email address"
/>
</div>
<div className="Field">
<label>
Password <sup>*</sup>
</label>
<input
value={password.value}
type="password"
onChange={(e) => {
setPassword({ ...password, value: e.target.value });
}}
onBlur={() => {
setPassword({ ...password, isTouched: true });
}}
placeholder="Password"
/>
{password.isTouched && password.value.length < 8 ? (
<PasswordErrorMessage />
) : null}
</div>
<div className="Field">
<label>
Role <sup>*</sup>
</label>
<select value={role} onChange={(e) => setRole(e.target.value)}>
<option value="role">Role</option>
<option value="individual">Individual</option>
<option value="business">Business</option>
</select>
</div>
<button type="submit" disabled={!getIsFormValid()}>
Create account
</button>
</fieldset>
</form>
</div>
);
}
export default App;
Reading
Step 1
The first step involves converting all form elements into controlled components. Since the pieces of local state have been already defined at the top of the component, you just have to assign each state piece to the value prop from each input element. To be able to account for state updates, each input should also define the onChange prop and call the state setter with the value property from the event target as parameter.
The password input is a special case that has an object as state instead of a string. As a result, the state setter should spread the previous values so they don’t get overridden. Finally, to make sure the password characters are obscured, you need to use the type “password” for the input.
Code
<div className="Field">
<label>
First name <sup>*</sup>
</label>
<input
value={firstName}
onChange={(e) => {
setFirstName(e.target.value);
}}
placeholder="First name"
/>
</div>
<div className="Field">
<label>Last name</label>
<input
value={lastName}
onChange={(e) => {
setLastName(e.target.value);
}}
placeholder="Last name"
/>
</div>
<div className="Field">
<label>
Email address <sup>*</sup>
</label>
<input
value={email}
onChange={(e) => {
setEmail(e.target.value);
}}
placeholder="Email address"
/>
</div>
<div className="Field">
<label>
Password <sup>*</sup>
</label>
<input
value={password.value}
type="password"
onChange={(e) => {
setPassword({ ...password, value: e.target.value });
}}
placeholder="Password"
/>
</div>
<div className="Field">
<label>
Role <sup>*</sup>
</label>
<select value={role} onChange={(e) => setRole(e.target.value)}>
<option value="role">Role</option>
<option value="individual">Individual</option>
<option value="business">Business</option>
</select>
</div>
Step 2
The isTouched property on the password state was defined to determine when the input was touched at least once. In order to listen for interactions, form inputs have two additional events you can subscribe to: onFocus and onBlur.
In this scenario, you need to use the onBlur event, which is called whenever the input loses focus, so that guarantees the user has interacted with the password input at least once. In that event, you should set the isTouched property to true with the password state setter.
Then, the condition to display the error message relies on that value being true and a check on the password length to see if it’s less than 8 characters long. If the condition is true, the component PasswordErrorMessage should be rendered. The final code should be as follows:
Code
<div className=”Field”>
<label>
Password <sup>*</sup>
</label>
<input
value={password.value}
type=”password”
onChange={(e) => {
setPassword({ …password, value: e.target.value });
}}
onBlur={() => {
setPassword({ …password, isTouched: true });
}}
placeholder=”Password”
/>
{password.isTouched && password.value.length < 8 ? (
<PasswordErrorMessage />
) : null}
</div>
If implemented correctly, the form should display an error message below the password field:
Step 3
To prevent the default behavior of the form when clicking on the submit button, you have to call preventDefault on the event object, right in your submit handler function.
const handleSubmit = (e) => {
e.preventDefault();
alert("Account created!");
clearForm();
};
Step 4
To fulfil the validation rules of the form, the body of the getIsFormValid function should be implemented as below:
const getIsFormValid = () => {
return (
firstName &&
validateEmail(email) &&
password.value.length >= 8 &&
role !== "role"
);
};
Below is an example of a valid form:
Step 5
Finally, to clear the form state after a successful submission, you should set each piece of state to its initial value:
const clearForm = () => {
setFirstName("");
setLastName("");
setEmail("");
setPassword({
value: "",
isTouched: false,
});
setRole("role");
};
Now, when you submit the form, an alert is displayed and right after you dismiss it, the form is reset to its initial values.
Practice Quiz: Self-review: Create a registration form
When setting a new value for the password state, that is represented by an object with two properties, value and isTouched, what’s the correct call to the setPassword state setter inside the onChange event handler? Select all that apply.
setPassword({ …password, value: e.target.value });
That’s correct, isTouched is preserved, since it’s been merged at the beginning in the state setter, before setting the new value.
What’s the correct event prop you should use to determine when an input has been interacted with at least once? Select all that apply.
onBlur
That’s correct, onBlur fires when the user leaves the focus from a particular input and it’s the best place to set the interaction state to true and provide actionable feedback in the UI if needed.
How do you prevent the default behavior of the form HTML tag in React when a submission event occurs?
By calling preventDefault on the event object inside the onSubmit function prop from the form tag.
That’s correct, that’s the proper way to prevent the default behavior and the right place to perform the call.
Practice Quiz: Knowledge check: Forms in React
What of the next input types doesn’t have a controlled version when they are used in React?
<input type=”file” />
That’s correct, because its value is read-only, it is an uncontrolled component in React.
What are some of the features of controlled components? Select all that apply
Enforcing a specific input format.
That’s correct, you can use regular expressions and match the React local state against them to provide instant feedback to users about a specific pattern, like credit cards or phone numbers. Alternatively, you can also control what characters are valid for a specific input and pass them through and ignore invalid ones
Validating all values in the client side when a submission occurs in the form, before calling the server endpoint.
That’s correct, you can access the different input states via React state and perform validation in the submit handler.
Conditionally disabling the submit button.
That’s correct, you can specify a condition based on the React state from the different inputs to disable the submit button.
How do you get the value of an input when its state is handled by the DOM (Uncontrolled)? Select all that apply.
Using a ref via useRef hook, assigning it to the input and then reading the input value when the submission happens via ref.current.value.
That’s correct, that’s the proper way to access the value from an uncontrolled input.
What happens when you click on the submit button in the below code snippet?
<form onSubmit={() => alert(“Submitting”)}>
<input type=”text” value={text} onChange={e => setText(e.target.value)} />
<input type=”button” value=”Submit” />
</form>
Nothing happens when the button is clicked.
That’s correct, the input should be of type submit, otherwise onSubmit callback from the form tag won’t fire.
What is missing in the below code for the select component to work properly?
<select onChange={handleChange}>
<option value=”grapefruit”>Grapefruit</option>
<option value=”lime”>Lime</option>
<option value=”coconut”>Coconut</option>
<option value=”mango”>Mango</option>
</select>
The select tag is missing a value prop.
That’s correct, the select tag is missing the current selection via the value prop.
Reading: Additional resources
Reading
Here is a list of additional resources for Module 1, Lesson 3 (Forms in React):
- Forms from the official React docs illustrate some examples of how React deals with certain form fields compared to traditional HTML tags, like the text area, select and file input tags. It also showcases how to handle multiple inputs by leveraging event.target.name and the implications of using null as a value in a controlled input.
- Formik is the most popular open source form library for React. It saves you lots of time when building forms and offers a declarative, intuitive and adoptable paradigm.
- Yup is an open-source library that integrates perfectly with Formik. It allows you to set all your form validation rules declaratively.
- React-hook-form is another popular library to easily manage your form state and validation rules.
React Context
Video: What you know about Props and State
React components are like blueprints for the user interface. They define the different elements that will be displayed on the page and how they are arranged. Props and state are the two types of data that React uses to build applications.
Props are immutable, meaning that they cannot be changed by the component that receives them. They are used to pass data from a parent component to a child component.
State is mutable, meaning that it can be changed by the component that owns it. It is used to store data that changes over time, such as the value of an input field or the results of a network request.
Here are some rules of thumb for deciding whether something should be a prop or state:
- If the data is passed from a parent component to a child component, it should be a prop.
- If the data needs to be changed by the component, it should be state.
- If the data is only used for rendering, it can be either a prop or state.
Stateless components are components that do not have any state. They are very simple and easy to understand. Stateful components are components that have state. They are more complex, but they allow you to create more dynamic and interactive user interfaces.
Here are some tips for designing React components:
- Avoid having too many components with state. State increases complexity and reduces predictability.
- Encapsulate client-server communication, data processing, and user event handling in stateful components.
- Move visualization and formatting logic into stateless components.
By following these tips, you can create React components that are efficient, maintainable, and easy to test.
imagine that little lemon has been such
a success that the restaurant will be expanding to other locations as
a part of the construction project. The architects have created
blueprints with the kitchen and dining areas set to be identical in size. Although the blueprints have been defined,
it will still be up to each restaurant manager to decide various things such as
the size, shape and number of tables, type of chairs, kitchen crockery and
utensils and wall collars. In this analogy, the blueprints for
the new locations are react components, whereas the specific configurations for
each location or what react props and state represent. So what are props and state props and state are both plain javascript or
Js objects. The react uses to hold information as you
progress through this video, you will discover the differences and similarities
between props and state and react. You’ll also learn how to identify
whether something falls into props or state and when state is needed as well as
how to differentiate between different react components based on props and state. While both props and
state influence the render output, they are different in one important
way props get passed to the component like parameters in a function where
state is managed within the component like variables declared within a function. So even though props and
state are inherently different, there are areas where they overlap,
notably when designing a component. Its main responsibility is to
translate raw data into rich html in the react ecosystem. The props and the state together
constitute the raw data that the html output derives from both props and
states are plain Js objects and are deterministic. This means your component always
generates the same output for the same combination of props and state. Another similarity is that props and
state changes. Both trigger a render update now. How do you know if something
goes inside props or state? The rule of thumb is that if a component
needs to alter one of its attributes at some point in time, that attributes
should be part of its state. Otherwise it should just be a prop for
that component. Let’s explore this in greater detail
props which is a shorthand for properties are a components configuration. They are received from
parents in the tree and are immutable as far as the component
receiving them is concerned. A component cannot change its props but
it is responsible for putting together the props
of its child components. In addition to prop react components have
another built in object named state. This object is a way to allow react to
determine when it should re render. A component react is set up so that any
change to the value served in the state, object will trigger a rear ender
of a given component states. Life cycle starts with a default
value when a component mount and then modifications of that
value happen over time. Mostly generated from user events. So state is a serialize double
representation of one point in time or in other words a snapshot A component
manages its own state internally, You could also say the state is private. Now another question you may ask when
designing a component is whether it should have any state at all. Well the answer is that state is optional
since state increases complexity and reduces predictability. A component without state is preferable. Although you can’t avoid having some
sort of state in an interactive app, you should avoid having too
many components with state. Finally, let’s examine one of the main
ways of differentiating types of react components based on props and state
components can be stateless or stateful. Stateless components have only props and
no state there’s not much going on besides the render function and all their logic
revolves around the props they receive. This makes them very easy to follow and
test on the other hand, stateful components have both props and
state. They’re in charge of client server,
communication, processing data and responding to user events. These sorts of logistics should be
encapsulated in a moderate number of state. Full components while all visualization
and formatting logic should move downstream into as many stateless
components as possible. Well done, you have completed this
lesson on the two types of data react users to build applications,
props and state going forward. You’ll be introduced to an additional
approach to managing information called context
What you know about Props and State in React
Props and state are two fundamental concepts in React. Props are immutable data that is passed from a parent component to a child component. State is mutable data that is managed by the component itself.
Props
Props are a way to pass data from a parent component to a child component. They are immutable, meaning that they cannot be changed by the child component.
To pass props to a child component, you use the props
attribute. For example:
JavaScript
function ParentComponent() {
const name = "Bard";
return (
<ChildComponent name={name} />
);
}
function ChildComponent(props) {
return (
<div>
<h1>Hello, {props.name}!</h1>
</div>
);
}
In this example, the ParentComponent
passes the name
prop to the ChildComponent
. The ChildComponent
then uses the name
prop to render a greeting to the user.
State
State is mutable data that is managed by the component itself. It is used to store data that changes over time, such as the value of an input field or the results of a network request.
To create state in a component, you use the useState
hook. For example:
JavaScript
import React, { useState } from "react";
function CounterComponent() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<div>
<h1>Count: {count}</h1>
<button onClick={handleClick}>Increment</button>
</div>
);
}
In this example, the CounterComponent
uses the useState
hook to create a state variable called count
. The count
variable is initialized to 0.
The handleClick
function increments the count
variable. When the Increment
button is clicked, the handleClick
function is called and the count
variable is incremented. This causes the CounterComponent
to re-render and display the updated count.
When to use props and state
Props are used to pass data from a parent component to a child component. State is used to store data that changes over time.
Here are some general guidelines for when to use props and state:
- Use props to pass data from a parent component to a child component that is not going to change.
- Use state to store data that changes over time.
- Use state to create interactive components.
- Avoid having too many components with state. State increases complexity and reduces predictability.
Conclusion
Props and state are two fundamental concepts in React. By understanding how to use them, you can create reusable and maintainable components.
Which of the following statements are true about state in React? Select all that apply.
State is managed within the component.
That’s correct. State is managed within the component, whereas props get passed to the component.
State is a plain JavaScript object that React uses to hold information.
That’s correct. State and props are both plain JavaScript or JS objects that React uses to hold information.
Attributes a component needs to change at some point in time shouldbe part of its state.
That’s correct. If a component needs to alter one of its attributes at somepoint in time, that attribute should be part of its state, otherwise, it should be a prop for that component.
Video: What is Context, and why is it used?
React Context API is a way to pass data through the component tree without having to pass props down manually at every level. This is useful for global state, such as the authenticated user or the current locale.
To use Context API, you first need to create a context object using the createContext()
function. This function takes a default value as an argument, which will be used if no provider is found.
Next, you need to create a provider component. This component wraps the UserContext.Provider
component and provides the context value to its descendants.
To consume the context, you can use the useContext()
hook. This hook takes the context object as an argument and returns the current context value.
In the example video, the author uses Context API to pass the authenticated user to the header and page components. This avoids having to pass the user prop down through multiple levels of the component tree.
Context API is a powerful tool for managing global state in React applications, but it is important to use it sparingly. Props and state should still be used for most data flow in your app.
In a typical React app, data is passed from parents to children via props in
a top-down fashion. However, there are certain
types of data that may be needed by many
components within an app. In these scenarios, using props, which is what React offers
us to pass data down, is not always effective. In this video, you’ll
be introduced to an alternative way of
passing data called context. You will learn more
about what it is and why it was introduced and
explore it in action. Let’s imagine
Little Lemon’s food ordering app offers a light or dark theme that changes the background and text
colors of all elements, or some general preferences
like a specific locale, depending on the
visitors’ geolocation that multiple components
should be aware of. What do these pieces of
data have in common? Well, they represent a global state for your
entire application. Now as your app grows in size, the same will happen
with a tree of components your app
is composed of. As mentioned earlier,
props is what React offers you
to pass data down. But in this scenario they can be cumbersome since
you will have to explicitly pass that data through every level of the tree, having intermediary
components that don’t really need the data and
just act as a proxy. This issue is commonly referred to as the props
drilling problem. The name says everything you need to know about the problem. Parent components
have to drill down props all the way to the children that
need to consume them. The way React has solved this
problem is by introducing the context application
programming interface or API. Context provides an alternative
way to pass data through the component tree
without having to pass props down manually
at every level. It is the right tool when you
need to share data that can be considered global for a
tree of React components. Let’s take some time to
examine context API in action. In this demonstration,
I am going to use a simple app I
created previously, which has been bootstrapped with Create React app and represents a simple blogging platform
that Little Lemon has to publish new innovative
recipes to their subscribers. It consists of a header
that contains a title and the current user that is authenticated on the top right. The rest is rendered
by the page component, which itself consists of
the user blog entries, each one with a title, content, and author name. Note that there are two
components that need to know the authenticated user; the logged in user component inside the header and
the page component. Because an authenticated user
falls into the nature of global data that needs to be shared across
several components, this is a clear example where context is the perfect
tool for the job. Let’s go ahead and create
the needed context, which I’m going to
call user context. Now, within the
user context file, you must follow the next steps. First, you need to import
createContext from React. This is the function
that gives you a new context object back. The function argument is the default value,
which in this case, I will declare as
undefined since the app doesn’t know beforehand who
the logged in user will be. Second, you need to create
a provider component. To do so, I will
call it UserProvider and render the
UserContext.Provider component. The UserContext.Provider
component is what allows consuming components to subscribe to context changes. This component
accepts a value prop, which is what will be
passed to consuming components that are
descendants of this provider. Now for this application, the value prop should be
the authenticated user, so I am going to define a
new piece of state for it. Note that this is an oversimplification
that already assumes a specific user, as in a real-world scenario, you will have to fetch
the authenticated user first and then set
it as a state. So now that the
state is defined, I will hook it to
the value prop. Next, it’s necessary
to provide a way for components to
subscribe to the context. For that, I am going to create a custom hook that wraps
the use context hook, which is the way to
consume a context value. This external function is
created just for convenience, so there’s no need to export the user context to
external components. As a side note, don’t worry if you’re not very
familiar with hooks yet, they will be covered in
depth in future lessons. The user context is now defined, but the app is still
not aware of it. For that, the provider
component is needed, so I’ll go ahead and wrap
the whole app with it. The last step is to consume the user context in the places where the username
has to be displayed, which are in the logged in user component and
the page component. I’ll go ahead and use the
custom hook defined earlier. Use user and destructure the authenticated
user from there. Finally, that information can be embedded in both render methods. The app now successfully
displays the name of the authenticated
user. Great work. You’ve learned about
context and why it’s used and worked through a practical
example of how to use it. But keep in mind that although context is useful
for global state, it’s still recommended
that you stick to props and state as
much as possible. That way your app data flow
will be easier to follow.
What is Context, and why is it used? in React
Context is a way to pass data through the component tree without having to pass props down manually at every level. This is useful for global state, such as the authenticated user or the current locale.
Why use Context?
There are a few reasons why you might want to use Context in your React application:
- To avoid prop drilling. Prop drilling is when you have to pass a prop down through multiple levels of the component tree. This can make your code difficult to read and maintain.
- To share global state. Context is a good way to share global state between components that are not directly related to each other.
- To create a more reusable component library. If you create components that use Context, you can make them more reusable by decoupling them from their specific context providers.
How to use Context
To use Context, you first need to create a context object using the createContext()
function. This function takes a default value as an argument, which will be used if no provider is found.
Next, you need to create a provider component. This component wraps the UserContext.Provider
component and provides the context value to its descendants.
To consume the context, you can use the useContext()
hook. This hook takes the context object as an argument and returns the current context value.
Here is a simple example of how to use Context:
JavaScript
// Create a context object.
const UserContext = createContext(null);
// Create a provider component.
function UserProvider({ children }) {
const [user, setUser] = useState(null);
return (
<UserContext.Provider value={user}>
{children}
</UserContext.Provider>
);
}
// Consume the context.
function Header() {
const user = useContext(UserContext);
return (
<header>
<h1>Hello, {user.name}!</h1>
</header>
);
}
// Wrap the app with the provider component.
function App() {
return (
<UserProvider>
<Header />
</UserProvider>
);
}
In this example, the UserProvider
component provides the current user to its descendants. The Header
component can then consume the context and display the user’s name.
Tips for using Context
Here are a few tips for using Context effectively:
- Use Context sparingly. Context should only be used for global state that needs to be shared between components that are not directly related to each other.
- Use clear and descriptive names for your context objects. This will make your code more readable and maintainable.
- Document your context providers and consumers. This will help other developers understand how to use your context.
Conclusion
Context is a powerful tool for managing global state in React applications. However, it is important to use it sparingly and carefully. By following the tips above, you can avoid the potential pitfalls of using Context and write better code.vv
Which of the following is true about the Context API? Select all that apply.
Context was introduced by React as a way to resolve the props drillingproblem.
That’s correct. React solved the problem of parent components having to drilldown props all the way to the children that need to consume them byintroducing the Context API.
Context should be used when you need to share global data.
That’s true. Context is useful for global state. It is the right tool when you needto share data that can be considered global for a tree of React components.
Lab: Exercise: Create a light-dark theme switcher
Reading: Solution: Create a light-dark theme switcher
Reading
Here is the completed solution code for the ThemeContext.js file:
Code
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext(undefined);
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider
value={{
theme,
toggleTheme: () => setTheme(theme === "light" ? "dark" : "light"),
}}
>
{children}
</ThemeContext.Provider>
);
};
export const useTheme = () => useContext(ThemeContext);
Here is the solution code for the Switch/index.js file:
Code
import "./Styles.css";
import { useTheme } from "../ThemeContext";
const Switch = () => {
const { theme, toggleTheme } = useTheme();
return (
<label className="switch">
<input
type="checkbox"
checked={theme === "light"}
onChange={toggleTheme}
/>
<span className="slider round" />
</label>
);
};
export default Switch;
Steps
Step 1
To create the ThemeProvider, the first step is to create a new context object, ThemeContext, using createContext, a function that can be imported from React. The default value argument is only used when a component does not have a matching Provider above it in the tree. This default value can be helpful for testing components in isolation without wrapping them. For the purpose of this exercise, it’s not relevant, so undefined can be used.
Then, inside the ThemeProvider component, you need to define a new piece of local state for the theme, which can be a string whose value is either “light” or “dark”. It can be initialized to “light”, which is usually the default theme for applications.
In the return statement, the ThemeContext.Provider component should be rendered and wrap the children.
Finally, recall that the value prop for ThemeContext.Provider is what gets injected down the tree as context. Since the application needs both the theme value and a way to toggle it, two values are injected: theme and toggleTheme.
theme is just the light-dark theme string value, whereas toggleTheme is a function that receives no parameters and just toggles the theme from light to dark and vice versa.
That completes the implementation of the ThemeProvider component, as per the code below:
Code
import { createContext, useContext, useState } from "react";
const ThemeContext = createContext(undefined);
export const ThemeProvider = ({ children }) => {
const [theme, setTheme] = useState("light");
return (
<ThemeContext.Provider
value={{
theme,
toggleTheme: () => setTheme(theme === "light" ? "dark" : "light"),
}}
>
{children}
</ThemeContext.Provider>
);
};
Step 2
The implementation for useTheme is quite simple. You just need to import the useContext hook from React and pass as an argument the ThemeContext object defined before. That allows your components to access both theme and toggleTheme values, which are the ones the useTheme custom hook returns.
export const useTheme = () => useContext(ThemeContext);
Step 3
The Switch component can then be connected to the toggleTheme function returned from useTheme as per the code below:
Code
const Switch = () => {
const { theme, toggleTheme } = useTheme();
return (
<label className="switch">
<input
type="checkbox"
checked={theme === "light"}
onChange={toggleTheme}
/>
<span className="slider round" />
</label>
);
};
Step 4
And, finally, you should be able to use the switch widget on the top right corner to change the theme of the application:
Practice Quiz: Self-review: Create a light-dark theme switcher
When creating a Provider component, what should you do with the children prop that it receives?
You should wrap the JSX that it returns with a Context Provider component and then pass the children through.
That’s correct, the children should be passed as a direct child of the Context Provider element.
Assuming that the default theme for the application is ‘light’, what should be the default value passed to the createContext call? Select all that apply. 1 point undefined null The string “light”
undefined , null, The string “light”
That’s correct, the default value is not relevant and can be any value. It’s only useful for testing components in isolation or as a default value when a context consumer does not have a Provider further up in the tree.
One of the parts of the context injected into the application is a function called toggleTheme. Assuming that the theme is held in some local state as a string that can be either ‘light’ or ‘dark’. What should be the exact implementation of the toggleTheme function?
toggleTheme: () => setTheme(theme === "light" ? "dark" : "light")
That’s correct, that’s the right implementation.
Reading: How re-rendering works with Context
Reading
In this reading you will learn about the default behavior of React rendering and when context is used. You will discover how to prevent unnecessary top-level re-renders with React.memo and how object references work in JavaScript. You will also learn how to utilize the useMemo hook to guarantee object references don’t change during re-rendering.
So far, you have learned that when a component consumes some context value and the value of this context changes, that component re-renders.
But what happens with all components in between? Is React wise enough to only re-render the consumers and bypass the intermediary components in the tree? Well, as it turns out, that doesn’t always happen and extra care should be taken when designing your React Context.
When it comes to the default behavior of React rendering, if a component renders, React will recursively re-render all its children regardless of props or context. Let’s illustrate this point with an example that uses some context.
Imagine the following component structure, where the top level component injects a Context provider at the top:
App (ContextProvider) > A > B > C
Code
const App = () => {
return (
<AppContext.Provider>
<ComponentA />
</AppContext.Provider>
);
};
const ComponentA = () => <ComponentB />;
const ComponentB = () => <ComponentC />;
const ComponentC = () => null;
If the outermost App component re-renders for whatever reason, all ComponentA, ComponentB and ComponentC components will re-render as well, following this order:
App (ContextProvider) -> A -> B -> C
If some of your top level components are complex in nature, this could result in some performance hit. To mitigate this issue, you can make use of the top level API React.memo().
If your component renders the same result given the same props, you can wrap it in a call to React.memo for a performance boost by memoizing the result.
Memoization is a programming technique that accelerates performance by caching the return values of expensive function calls.
This means that React will skip rendering the component, and reuse the last rendered result. This is a trivial case for ComponentA, since it doesn’t receive any props.
const ComponentA = React.memo(() => <ComponentB />);
React.memo takes the component definition as a first argument. An optional second argument can be included if you would like to specify some custom logic that defines when the component should re-render based on previous and current props.
After that little adjustment, you will prevent any rendering from happening in all ComponentA, ComponentB and ComponentC if the App component re-renders.
Code
const App = () => {
return (
<AppContext.Provider>
<ComponentA />
</AppContext.Provider>
);
};
const ComponentA = React.memo(() => <ComponentB />);
const ComponentB = () => <ComponentC />;
const ComponentC = () => null;
A good rule of thumb is to wrap the React component right after your context provider with React.memo.
In real-life applications, you will find yourself in need of passing several pieces of data as context value, rather than a single primitive like a string or number, so you’ll be working most likely with JavaScript objects.
Now, according to React context rules, all consumers that are descendants of a provider will re-render whenever the provider’s value prop changes.
Let’s go through the following scenario built upon the previous example, where the context value that gets injected is defined as an object called value with two properties, ‘a’ and ‘b’, being both strings. Also, ComponentC is now a consumer of context, so any time the provider value prop changes, ComponentC will re-render.
Code
const App = () => {
const value = {a: 'hi', b: 'bye'};
return (
<AppContext.Provider value={value}>
<ComponentA />
</AppContext.Provider>
);
};
const ComponentA = React.memo(() => <ComponentB />);
const ComponentB = () => <ComponentC />;
const ComponentC = () => {
const contextValue = useContext(AppContext);
return null;
};
Imagine that the value prop from the provider changes to {a: ‘hello’, b: ‘bye’}.
If that happens, the sequence of re-renders would be:
App (ContextProvider) -> C
That’s all fine and expected, but what would happen if the App component re-renders for any other reason and the provider value doesn’t change at all, being still {a: ‘hi’, b: ‘bye’}?
It may be a surprise to you to find out that the sequence of re-renders is the same as before:
App (ContextProvider) -> C
Even though the provider value doesn’t seem to change, ComponentC gets re-rendered.
To understand what’s happening, you need to remember that in JavaScript, the below assertion is true:
{a: ‘hi’, b: ‘bye’} !== {a: ‘hi’, b: ‘bye’}
That is because object comparison in JavaScript is done by reference. Every time a new re-render happens in the App component, a new instance of the value object is created, resulting in the provider performing a comparison against its previous value and determining that it has changed, hence informing all context consumers that they should re-render.
This problem can be resolved by using the useMemo hook from React as follows.
Code
const App = () => {
const a = 'hi';
const b = 'bye';
const value = useMemo(() => ({a, b}), [a, b]);
return (
<AppContext.Provider value={value}>
<ComponentA />
</AppContext.Provider>
);
};
const ComponentA = React.memo(() => <ComponentB />);
const ComponentB = () => <ComponentC />;
const ComponentC = () => {
const contextValue = useContext(AppContext);
return null;
};
Hooks will be covered in depth in the next module, so don’t worry too much if this is new for you.
For the purpose of this example, it suffices to say that useMemo will memoize the returned value from the function passed as the first argument and will only re-run the computation if any of the values are passed into the array as a second argument change.
With that implementation, if the App re-renders for any other reason that does not change any of ‘a’ or ‘b’ values, the sequence of re-renders will be as such:
App (ContextProvider)
This is the desired result, avoiding an unnecessary re-render on ComponentC. useMemo guarantees keeping the same object reference for the value variable and since that’s assigned to the provider’s value, it determines that the context has not changed and should not notify any consumer.
Conclusion
You have learned about how re-rendering works in React when context is used and how React.memo and useMemo APIs from React can help you perform some optimizations to avoid unnecessary re-renders in your components tree.
Practice Quiz: Knowledge check: React Context
What of the below scenarios are valid for choosing context instead of local state? Select all that apply.
The visibility state of an alert that overlays into the whole application.
That’s correct, global alerts are well suited for context since any component can trigger them.
The locale or language that should be used in the application’s text.
That’s correct, since that’s global state that affects all component’s text.
AI assistant
The following scenarios are valid for choosing context instead of local state:
- The visibility state of an alert that overlays into the whole application.
- The locale or language that should be used in the application’s text.
Context is a good choice for data that needs to be shared across multiple components, such as the visibility state of an alert or the locale of the application. Local state is a good choice for data that is only needed by a single component.
For example, if you have an alert that overlays into the whole application, you would want to use context to store the visibility state of the alert. This way, any component in the application can access the visibility state and update the UI accordingly.
Similarly, if you want to support multiple languages in your application, you would use context to store the locale. This way, any component in the application can access the locale and display the text in the correct language.
The current selection of a group of radio buttons is not a valid scenario for choosing context over local state. This is because the radio buttons are only relevant to the component that contains them. There is no need to share the selection state of the radio buttons with other components in the application.
In conclusion, context is a good choice for data that needs to be shared across multiple components, such as the visibility state of an alert or the locale of the application. Local state is a good choice for data that is only needed by a single component.
What is the problem of props drilling? Select all that apply.
Components having to pass down props all the way to the children that need to consume them.
That’s correct, components drill down props across several levels to reach the children that need them.
Components receiving more props than they should.
That’s correct, props drilling involves components receiving props that they don’t use or need at all.
AI assistant
All of the following are problems with props drilling:
- Components having to pass down props all the way to the children that need to consume them. This can make the code difficult to read and maintain, especially if the component hierarchy is deep.
- Components not knowing the local state of their parents. This can make it difficult for components to update their UI when their parent’s state changes.
- Components receiving more props than they should. This can make the components more complex and difficult to test.
In addition to these problems, props drilling can also lead to performance issues. When props are passed down through a deep component hierarchy, it can add overhead to the rendering process.
To avoid props drilling, you can use context or a state management library such as Redux. Context allows you to share data between components without having to pass props through every level of the component tree. Redux is a state management library that provides a central store for application state. This makes it easy to keep track of state and ensure that all components are receiving the correct data.
Here are some examples of how to avoid props drilling:
- Use context to share the global state of your application, such as the current user or the selected language.
- Use a state management library such as Redux to manage the state of your application.
- Break down complex components into smaller, more manageable components.
- Use props to pass data between components that are directly related to each other.
By following these tips, you can avoid props drilling and create more maintainable and efficient React applications.
When creating a new piece of application state, what is the bare minimum of React APIs you would need to define it?
Context and local state.
That’s correct, you need local state to define the global state and Context to inject it into a tree.
AI assistant
To define a new piece of application state in React, you will need to use the useState hook. The useState
hook allows you to create and manage state variables within a functional component.
For example, the following code defines a new piece of state called count
:
JavaScript
const [count, setCount] = useState(0);
The count
variable is the initial state of the component, and the setCount
function is used to update the state.
Once you have defined your state variable, you can use it in your component’s render function:
JavaScript
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
When the user clicks the button, the setCount
function is called to update the count
state variable. This causes the component to re-render, and the updated count value is displayed in the UI.
Bare minimum of React APIs to define application state
The useState
hook is the bare minimum of React APIs that you need to define application state. However, you may also want to use other APIs, such as context or Redux, to manage more complex state.
Context is a good choice for state that needs to be shared across multiple components. Redux is a good choice for state that needs to be managed centrally.
Which API you choose depends on the specific needs of your application.
Conclusion
To define a new piece of application state in React, you will need to use the useState
hook. The useState
hook allows you to create and manage state variables within a functional component.
You may also want to use other APIs, such as context or Redux, to manage more complex state.
What happens when the value prop of the Context Provider changes?
All the consumer components re-render with the updated value.
That’s correct, all components subscribed to that context get updated.
AI assistant
When the value prop of the Context Provider changes, all of the consumer components that are subscribed to the context re-render with the updated value. This is because React uses a dependency tracking algorithm to determine which components need to re-render when state changes.
The Context Provider component itself does not re-render when its value prop changes. However, the whole component tree under the Context Provider will re-render, because all of the consumer components will re-render.
Here is an example:
JavaScript
import React, { useState, useContext } from "react";
const MyContext = React.createContext();
function Provider({ value }) {
const [contextValue, setContextValue] = useState(value);
return (
<MyContext.Provider value={contextValue}>
{children}
</MyContext.Provider>
);
}
function Consumer() {
const contextValue = useContext(MyContext);
return (
<div>
<h1>Context value: {contextValue}</h1>
</div>
);
}
function App() {
const [count, setCount] = useState(0);
return (
<Provider value={count}>
<Consumer />
<button onClick={() => setCount(count + 1)}>Increment</button>
</Provider>
);
}
In this example, the Provider
component provides the value of the count
state variable to all of the consumer components. When the user clicks the button, the count
state variable is updated, and all of the consumer components re-render with the updated value.
This is a very basic example, but it should give you a good understanding of how context works in React.
What happens when you wrap a component with the React.memo API, such as React.memo(Component). Select all that apply.
Whether the component should re-render could be determined by some custom logic that uses the previous props and the current props.
That’s correct, you can provide an additional function that receives previous props and current props to determine if an update should occur.
React provides a performance optimization.
That’s correct, it avoids unnecessary re-renders automatically.
AI assistant
The following statements are true about wrapping a component with the React.memo API:
- React provides a performance optimization.
- Whether the component should re-render could be determined by some custom logic that uses the previous props and the current props.
When you wrap a component with the React.memo API, React will compare the previous props and the current props to determine whether the component should re-render. If the props are the same, React will skip re-rendering the component. This can improve performance, especially for components that are rendered frequently.
You can also provide a custom comparison function to the React.memo API. This function will be used to determine whether the component should re-render. The custom comparison function can take into account any factors that you want, such as the component’s state or the context in which it is rendered.
The following statement is not true about wrapping a component with the React.memo API:
- The component never gets updated no matter if there was a change in its local state or the props it receives.
If the component’s local state changes, or if the props it receives change, the component will re-render, even if it is wrapped with the React.memo API.
Conclusion
Wrapping a component with the React.memo API can improve performance, but it is important to note that it will not prevent the component from re-rendering if its local state changes or if the props it receives change.
Video: Module summary: Components
In this module on React components, you learned the following:
- How to render lists with React, using the
map()
method and JSX. - The concept of keys, and how to choose the right key for your use case.
- How to use controlled components to manage the state of form elements.
- The difference between props and state, and when to use each one.
- How to use the Context API to avoid props drilling.
This is a great start to mastering React components. Keep up the good work!
Well done. You’ve reached the end of this module
on react components. Let’s take a few minutes to review what you have
learned so far. You began the module with
a comprehensive lesson on how to render
lists with react. You were introduced to the
map method in JavaScript, which can be used with a race to perform transformation
operations. Is a useful tool when
dealing with data from an external provider
that you’d like to display differently
in your app. You also learned how to
transform any list of items in JavaScript using the
map method first hand. Next, you discovered how to use that map method
function along with JSX to render a
list of components and transform a collection
of elements with react. Finally, you gained an understanding of
the concept of keys, followed by a practical set
of guidelines that help you choose the right key
depending on your use case. You learned that keys are
identifier’s that help react to determine which items have changed or added or are removed, as well as instruct react how to treat a
specific element when an update occurs
and whether it’s internal state should
be preserved or not. You’ve also discovered
the keys can be used when you need to
provide explicit information that tells react how
to behave when your UI changes when dealing
with a list of items. You learned that the general
rule with keys is to use a stable identifier that is
unique among its siblings, which is why the key used most often is a unique
ID from your data. You then learned that
it is possible to use indexes as keys
as a last resort, but that this can negatively
impact performance if the order of your list
items is likely to change. Next, you move down to our
lesson on forums and how react treats them differently compared to traditional HTML versions. You were first introduced
to controlled components, which are a set of
components that offer a declarative
API to enable full control of the
state of form elements at any point and time
using react state. You learned how to convert any traditional HTML form into a react form using a set
of controlled components. In other words, you learned how to transform an
uncontrolled form into a controlled version using local state and the
on change event, as well as the on submit prop. You also discovered some
of the advantages of controlled components compared to uncontrolled
components. For example, it makes
it possible for you to have more control
over form submission, such as disabling
the submit button when the form is invalid. Last, you were taught
how to implement a feedback form and
in relation to this, how to perform any
custom validation logic before the submission
of the form occurs. The final lesson began with
a recap of props and state. You learn to clearly
differentiate between props and state and when to
use one or another. Recall that although
props and state have similarities, for example, they’re both plain
JavaScript objects that React uses to
hold information. Props get pass to the component where state is managed
within the component. Key takeaways included
that if a component needs to alter one of its
attributes at some point, then that attribute should
be part of its state. Otherwise, it should
just be a prompt for that component and that a component without
state is preferable. You also learned about stateless components,
which have props, but no state, and stateful
components which have both. After that, you cover the
problem of props drilling, and how it affects your
components modularity. As parent components
have to drill down props all the
way to the children, they need to consume them. You were introduced
to Context API as a solution to this problem
and discovered how to use it to encapsulate any
piece of global state and avoid manually passing props
down between components. The power of React Context was illustrated as a viable
alternative to local state. Well, I think that’s a fantastic start on your
journey to mastering react. Looking forward to working
with you in the next module.
Quiz: Module quiz: Components
When using a key for your list items, what’s the best general choice?
Using an ID coming from the data, that points to the database ID.
That’s correct, that’s the preferred option.
Imagine you have a specification for rendering the following list item:
Ice cream – 200 cal
, where the name and the number of calories are coming as dynamic data. Select all the options that would correctly render the desired output:
<li>{item.name} – {item.cal} cal</li>
That’s correct, that would render the desired output using JSX syntax.
<li>{`${item.name} – ${item.cal} cal`}</li>
That’s correct, that would render the desired output using JSX syntax and string interpolation.
Let’s suppose you have a list of two items and a new item is added to the list. From the point of view of the React diffing algorithm, what’s the most optimal position for the new element added? Select all that apply
The new element added at the end.
That’s correct, that’s the most optimal path.
What are controlled components?
A set of components whose internal state is controlled by React.
That’s correct, state is delegated from the DOM to React local state.
What are the features you can still achieve with uncontrolled components? Select all that apply
One time value retrieval on submit using a React ref.
That’s correct, the ref allows you to access the internal state held by the DOM.
Validation on submit.
That’s correct, in the submit handler function you can use refs to access all the input values and perform any custom client validation.
When creating an API for context consumers via useContext, what’s the argument you have to provide to the useContext call?
The Context object obtained via the createContext call.
That’s correct, you always have to pass a context object as argument to the useContext hook.
Imagine the below component structure, where all components ComponentA, ComponentB and ComponentC are simple presentational components that hold no props or state:
const App = () => {
return(
<AppContext.Provider>
<ComponentA />
</AppContext.Provider>
);
};
const ComponentA = React.memo(() => <ComponentB />);
const ComponentB = () => <ComponentC />;
const ComponentC = () => null;
If the App component re-rendered for whatever reason, what would be the sequence of component re-renders that would take place?
App
That’s correct, since ComponentA is wrapped with React.memo, it will prevent unnecessary updates within itself and down the tree, so only the App component would update.
Even though props and state are inherently different, what are areas where they overlap? Select all that apply.
Both props and state are plain JS objects.
That’s correct, they are both plain JS objects.
Both props and state changes trigger a render update.
That’s correct, as soon as one or the other update, it will trigger a re-render.
Both props and state are deterministic, meaning that your component always generates the same output for the same combination of props and state.
That’s correct, React components are pure functions when it comes to their rendering output.
When defining a JavaScript object as a piece of local React state that will be injected as context, what is the specific React hook that allows you to keep the same object reference in memory and prevent unnecessary re-renders if the object itself hasn’t changed any values?
useMemo
That’s correct, useMemo keeps in memory the previous object reference and if no changes occur in the object values, it will reuse the same reference on subsequent updates.
What are some possible examples of application features that are well suited to be defined as React context? Select all that apply
The application theme. Locale preferences. The current authenticated user.
Reading: Additional resources
Reading