Table of contents
- So far, we have learned about components. Now let's explore how to add and manage dynamic content in components.
- What is State in React?
- What are Props in React?
- Student Component
- StudentList Component
- Hooks in React
- useState Hook
- useEffect Hook
- React Component Lifecycle
- A Surprise Content at the End
- Conclusion
So far, we have learned about components. Now let's explore how to add and manage dynamic content in components.
What is State in React?
State in React is an object that contains information about the component, including its properties and their values.
For example:
function Student() {
const studentState = {
name: 'Dheeraj',
age: 21
};
return (
<h2>Hello, I'm {studentState.name} and I'm {studentState.age} years old.</h2>
);
};
export default Student;
Now you can manage and manipulate the state using the useState
hook, which we will discuss later in this blog.
What are Props in React?
Props refer to properties that can be passed to a child component as arguments. It allows us to customize the behavior of a component. Let's take an example to understand this concept.
In the previous example, we created the Student
component, where the data was static. However, if we want to display different names and ages for the Student
component, we can achieve this using props.
Let's modify the Student
component and create a new component called StudentList
.
Student Component
import React from 'react';
function Student(props) {
return (
<h2>Hello, I'm {props.student.name} and I'm {props.student.age} years old.</h2>
);
};
export default Student;
StudentList Component
import React from 'react';
import Student from './Student';
function StudentList() {
const studentList = [
{
name: 'Dheeraj',
age: 21
},
{
name: 'Suraj',
age: 25
}
]
return (
<ul>
{
studentList.map(student => {
return (
<li>
<Student student={student} />
</li>
);
})
}
</ul>
);
};
export default StudentList;
Hooks in React
Hooks in React are functions that are used to manipulate the state and perform actions when there is a change in the component's lifecycle. As mentioned earlier, we will now discuss the useState
hook.
useState Hook
The useState
hook is used to manage and manipulate the state of a React component. It returns an array containing two elements:
Getter Variable: A variable that allows us to access the state.
Setter Function: A function that is used to change the state.
Let's see an example by making changes to the StudentList
component:
import React, { useState } from 'react';
import Student from './Student';
function StudentList() {
const studentList = [
{
name: 'Dheeraj',
age: 21
},
{
name: 'Suraj',
age: 25
}
]
const [showStudents, setShowStudents] = useState(false);
function changeShowStudents() {
setShowStudents(!showStudents);
}
if (!showStudents) {
return (
<button onClick={changeShowStudents}>Show Students</button>
);
} else {
return (
<>
<button onClick={changeShowStudents}>Hide Students</button>
<ul>
{
studentList.map(student => {
return (
<li>
<Student student={student} />
</li>
);
})
}
</ul>
</>
);
}
};
export default StudentList;
In the above code, useState(false)
returns an array where showStudents
is a variable representing the current value of the state, and setShowStudents
is a function used to update the state.
Here, using the useState
hook, we dynamically changed the showStudents
state.
useEffect Hook
Before we discuss the useEffect
hook, let's understand the lifecycle phases of a React component:
React Component Lifecycle
A component goes through the following phases:
Mounting: When the component is added to the DOM for the first time.
Update: When there is a change in the component's state or props.
Unmounting: When the component is removed from the DOM.
The useEffect
hook is called whenever there is a side effect (mounting, update, or unmounting). It takes two arguments: a callback function that describes what to do when there is a side effect, and an array of variables that the hook should watch for changes.
The
useState
hook should be used when you need a dynamic variable that affects your UI logic or causes UI changes.The
useEffect
hook should be used to detect any changes in the component lifecycle.
For example:
import React, { memo, useEffect } from 'react';
import ProductCard from '../ProductCard';
import styles from './ProductList.module.css';
import { useDispatch, useSelector } from 'react-redux';
import { loadingProducts } from '../../Store/Products';
function ProductList({ categoryId }) {
console.log('ProductList rendered');
const dispatch = useDispatch();
const products = useSelector(state => state.productList);
useEffect(() => {
dispatch(loadingProducts(categoryId));
}, [categoryId, dispatch]);
if (!categoryId) {
return <div>Select a Category</div>;
} else if (products.isLoading) {
return <div>Loading...</div>;
} else if (products.products.length > 0) {
return (
<div className={styles.list}>
{products.products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
} else {
return <div>No products found. Choose a different category.</div>;
}
};
export default memo(ProductList);
This code is a React component called ProductList
that renders a list of products based on the provided categoryId
. Here's a breakdown of the code:
The component imports necessary dependencies from React, such as
React
,memo
, anduseEffect
, and also imports theProductCard
component.It imports the CSS module
ProductList.module.css
for styling.The component uses the
useDispatch
and `use
Selectorhooks from
react-reduxto interact with the Redux store. 4. The
ProductListcomponent receives a
categoryIdprop. 5. The component defines a
dispatchvariable to dispatch actions to the Redux store and uses
useSelectorto select the
productListstate from the store. 6. The component uses the
useEffecthook to dispatch the
loadingProductsaction when the
categoryIdor
dispatchdependencies change. This action is responsible for fetching the products based on the provided
categoryId`. 7. Inside the component, there are conditional rendering statements:
If
categoryId
is not provided, it returns a message asking to select a category.If the
products.isLoading
flag is true, it returns a loading message.If there are products available, it renders a list of
ProductCard
components using theproducts.products
array. EachProductCard
component receives a uniquekey
prop and the correspondingproduct
object.If there are no products available, it returns a message indicating that no products were found in the selected category.
- The
ProductList
component is exported usingmemo
to optimize performance by memoizing the component and preventing unnecessary re-renders.
Overall, this component fetches and renders a list of products based on the provided category ID, displaying loading messages or appropriate feedback based on the loading status and availability of products.
When we want to run
useEffect
only on the first render, we pass an empty array as the dependency.
A Surprise Content at the End
Virtual DOM
Whenever we make a change in the DOM, it incurs a significant cost. In a complex application, there can be numerous changes made.
To minimize this cost, React uses a concept called the Virtual DOM.
The Virtual DOM is a virtual representation of the real DOM, represented in JSON format.
For example, let's create a component:
function App() {
return (
<ul className="list">
<li>
<a className="item-1">Item 1</a>
</li>
<li>
<a>Item 2</a>
</li>
<li>
<a>Item 3</a>
</li>
</ul>
);
}
The structural tree of the component would look like this:
And the JSON representation would be:
let vdom = {
nodeName: "ul",
properties: {
className: "list",
children: [
{
nodeName: "li",
properties: {
children: [
{
nodeName: "a",
properties: {
className: "item-1",
children: ["Item 1"]
}
}
]
}
},
{
nodeName: "li",
properties: {
children: [
{
nodeName: "a",
properties: {
children: ["Item 2"]
}
}
]
}
},
{
nodeName: "li",
properties: {
children: [
{
nodeName: "a",
properties: {
children: ["Item 3"]
}
}
]
}
}
]
}
}
How Virtual DOM Works
React maintains two versions of the Virtual DOM: the current Virtual DOM and the updated Virtual DOM.
When there is an update, React uses an algorithm to determine the changes.
Instead of updating the entire DOM, React only makes changes to the specific part of the DOM where the update occurred.
This approach ensures that only the necessary parts of the DOM are re-rendered, improving performance.
Conclusion
I hope you found this blog post helpful. Please like and share it if you did.
Thank you!