How to Update Child and Parent Components in React.js
February 4th, 2025 | By Jay Raj | 12 min read
In this tutorial, you'll learn how to update component states in your React application. States would need to be updated from the component, which is pretty straightforward. Here, we'll try to focus on updating the parent component state from a child component and updating the child component state from the parent component. Let's get started.
Updating Child and Parent Components in React.js
For the sake of this tutorial, we'll be using the Next.js 14 framework. Make sure you have Node.js 18 or later installed in your system. Let's get started by creating a web app using the Next.js framework.
npx create-next-app@14
The above command would ask for a couple of questions; please mark the following answers,
√ What is your project named? ... parent-child
√ Would you like to use TypeScript? ... Yes
√ Would you like to use ESLint? ... No
√ Would you like to use Tailwind CSS? ... No
√ Would you like to use `src/` directory? ... Yes
√ Would you like to use App Router? (recommended) ... Yes
√ Would you like to customize the default import alias (@/*)? ... No
Creating a new Next.js app in D:\Workspace\parent-child.
That would create the Next.js project with some boilerplate code. Navigate to the project folder and run the project.
cd parent-child
npm run dev
You'll be having the application running at http://localhost:3000/.
Inside the `src/app` you have the main page and it's layout. For the sake of this tutorial, we'll create a separate page called `src/app/dashboard/page.tsx` and it's corresponding layout called `src/app/dashboard/layout.tsx`.
typescript
const DashboardPage = () => {
return (
<div>
Welcome to DashboardPage
</div>
);
};
export default DashboardPage;
typescript
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<div>
{children}
</div>
);
}
Save the above changes and navigate to http://localhost:3000/dashboard and you'll have the dashboard page.
Creating the Components
Let's create a Menu component, which we'll be using to show a menu on our dashboard page. Create a folder called `src/components` where we'll keep all our components. Inside components create a Menu component. Here is how the `components/Menu/Menu.tsx` file looks:
typescript
import React from 'react';
import './Menu.css';
// Sample dummy data
const menuItems = [
{ id: 1, name: 'Home' },
{ id: 2, name: 'About' },
{ id: 3, name: 'Services' },
{ id: 4, name: 'Contact' },
];
const Menu = () => {
return (
<nav>
<ul>
{menuItems.map(item => (
<li key={item.id}>
<a href="javascript:void(0);" >{item.name}</a>
</li>
))}
</ul>
</nav>
);
};
export default Menu;
In the above code, we have a list of menu items that are being iterated to display a menu in the UI.
Add the following style for Menu component inside `components/Menu/Menu.css`.
css
nav {
background-color: #f8f9fa;
padding: 20px;
}
ul {
display: flex;
justify-content: space-around;
margin: 0;
padding: 0;
list-style: none;
}
li {
margin: 0 15px;
}
a {
color: #007bff;
transition: color 0.3s;
}
a:hover {
color: #0056b3;
}
Now create a wrapper component for the Dashboard page inside `components/Dashboard/Dashboard.tsx`. Here is how the file looks:
typescript
import Menu from '../Menu/Menu';
const DashboardWrapper = () => {
return (
<div>
<Menu />
</div>
);
};
export default DashboardWrapper;
As you would have noticed, we have called `Menu` component inside the `DashboardWrapper` component.
Modify `src/app/dashboard/page.tsx` to include `DashboardWrapper`.
typescript
import DashboardWrapper from "@/components/Dashboard/Dashboard";
const DashboardPage = () => {
return (
<>
<DashboardWrapper />
</>
);
};
export default DashboardPage;
Save the above changes and refresh the web app. The menu will be rendered in your application.
Update Parent State from Child
Now here `Menu` component is the child and `DashboardWrapper` is the parent. To update parent component state from the child component, you can pass in a callback function to the Menu component.
jsx
<Menu menuClickCallback={handleMenuClick} />
Define the `handleMenuClick` inside the `DashboardWrapper` component.
typescript
const handleMenuClick = (name: string) => {
console.log(`${name} clicked`);
}
Modify the child component `Menu.tsx` to accept the callback handler and pass the menu click to the parent callback.
typescript
import React from 'react';
import './Menu.css';
// Sample dummy data
const menuItems = [
{ id: 1, name: 'Home' },
{ id: 2, name: 'About' },
{ id: 3, name: 'Services' },
{ id: 4, name: 'Contact' },
];
const Menu = ({menuClickCallback}: any) => {
return (
<nav>
<ul>
{menuItems.map(item => (
<li key={item.id}>
<a href="javascript:void(0);" onClick={() => menuClickCallback(item.name)} >{item.name}</a>
</li>
))}
</ul>
</nav>
);
};
export default Menu;
As you would have noticed, the Menu component accepts `menuClickCallback` as a prop and uses the same for `onClick` inside the anchor tag click. Save the above changes and refresh the app. Then click on the menu and check, and you'll see that the menu's name is logged in the browser console.
Now define another state variable inside the `DashboardWrapper`.
typescript
const [menu, setMenu] = useState("");
Let's update the `menu` inside the `handleMenuClick`.
typescript
const handleMenuClick = (name: string) => {
setMenu(name);
}
Let's render the `menu` inside the UI once it has been selected. For that you need to modify the `DashboardWrapper`.
jsx
return (
<div>
{
menu && menu.length > 0 && <span>
Selected menu is {menu}
</span>
}
<Menu menuClickCallback={handleMenuClick} />
</div>
);
Here is what the complete `DashboardWrapper` looks like:
typescript
'use client';
import { useState } from 'react';
import Menu from '../Menu/Menu';
const DashboardWrapper = () => {
const [menu, setMenu] = useState("");
const handleMenuClick = (name: string) => {
setMenu(name);
}
return (
<div>
{
menu && menu.length > 0 && <span>
Selected menu is {menu}
</span>
}
<Menu menuClickCallback={handleMenuClick} />
</div>
);
};
export default DashboardWrapper;
You need to use `use client` at the top of the file since we use `useState` inside the `DashboardWrapper,` meaning it's no longer a server component.
Save the above changes and refresh the app. Click on the menu item, and it will reflected on the UI. So this is how you can update the parent component state from the child component.
Update Child State from Parent
Let's see how you can update the state in the child component from a parent. To do so, you need to lift the child state to the parent component and pass the updating function to the child, which can be called as and when required.
Initialize the child state inside the parent `DashboardWrapper`.
typescript
const [childState, setChildState] = useState({
msg : 'Hello'
});
Pass the `childState` and its update function to the `Menu` child component.
jsx
<Menu menuClickCallback={handleMenuClick} prefix={prefix} updatePrefix={setMenuPrefix} childState={childState} updateChild={setChildState} />
Modify the child component `Menu` to update the props and display the state variable `msg` in the UI. Here is what the child component looks like:
jsx
import React, { useState } from 'react';
import './Menu.css';
// Sample dummy data
const menuItems = [
{ id: 1, name: 'Home' },
{ id: 2, name: 'About' },
{ id: 3, name: 'Services' },
{ id: 4, name: 'Contact' },
];
const Menu = ({ prefix, menuClickCallback, updatePrefix, childState, updateChild }: any) => {
const getMenuName = (name: string, prefix: string) => {
if (prefix?.length) {
return `${prefix}${name}`
}
return name;
}
const updateMenuPrefix = () => {
const msg = prompt('Enter menu prefix');
updatePrefix(msg);
}
return (
<>
<nav>
<ul>
{menuItems.map(item => (
<li key={item.id}>
<a href="javascript:void(0);" onClick={() => menuClickCallback(item.name)} >{getMenuName(item.name, prefix)}</a>
</li>
))}
</ul>
</nav>
<button onClick={updateMenuPrefix}>Update Menu Prefix</button>
<div>
{childState.msg}
</div>
</>
);
};
export default Menu;
Modify the parent component `DashboardWrapper` to add a button to update the child state.
jsx
<button onClick={updateChildState}>
Update Child State
</button>
Also, add the `updateChildState` method to update the state variable.
typescript
const updateChildState = () => {
const msg = prompt('Enter child message');
setChildState((prev:any)=>({
...prev,
['msg']: msg
}));
}
In the `updateChildState` method, we use `setChildState` to update the state. We use the spread operator to use the existing values as they are and modify the `msg` value.
Here is what the complete `DashboardWrapper` component looks like:
typescript
'use client';
import { useState } from 'react';
import Menu from '../Menu/Menu';
const DashboardWrapper = () => {
const [menu, setMenu] = useState("");
const [prefix, setMenuPrefix] = useState("");
const [childState, setChildState] = useState({
msg: 'Hello'
});
const handleMenuClick = (name: string) => {
setMenu(name);
}
const updateChildState = () => {
const msg = prompt('Enter child message');
setChildState((prev: any) => ({
...prev,
['msg']: msg
}));
}
return (
<div>
{
menu && menu.length > 0 &&
<>
<span>
Selected menu is {menu}
</span>
</>
}
<Menu menuClickCallback={handleMenuClick} prefix={prefix} updatePrefix={setMenuPrefix} childState
{childState} updateChild={setChildState} />
<button onClick={updateChildState}>
Update Child State
</button>
</div>
);
};
export default DashboardWrapper;
Save the above changes and click the `Update Child State` button. The message will be asked to update the child state. Enter the message, and the child state will be updated.
Here, we just used the updated child state from the parent component. You can even pass the method to the child component and try to update the `childState` from the child component itself.
Wrapping it up
In this tutorial, you learned how to update states in your react components, how to update the parent component from the child component, and vice versa.
Jscrambler
The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.
View All ArticlesMust read next
Understanding Context API In React.js
In this tutorial, you'll learn about the Context API which is used for passing or sharing data across components in React.js.
September 9, 2022 | By Jay Raj | 9 min read
Protecting Your React.js Source Code with Jscrambler
In this step-by-step guide, you'll learn how to protect your React.js application with Jscrambler to prevent code theft and reverse-engineering.
February 1, 2019 | By Jscrambler | 6 min read
