Sitemap

Props Hell and How Do We Get Escape of a Props Hell

2 min readOct 11, 2025

--

Props Hell

Refers to the complex and inflexible predicament that occurs in component-based frameworks like React, where data is constantly passed as props across deep component trees.

1.App.js

// App.js
import React from "react";
import Page from "./Page";

function App() {
const user = {
name: "John",
surname: "Doe",
email: "johndoe@example.com",

};

return <Page user={user} />;
}

export default App;

2. Page.js

// Page.js
import React from "react";
import Dashboard from "./Dashboard";

function Page({ user }) {
// we only receive user data to transmit
return <Dashboard user={user} />;
}

export default Page;

3. Dashboard.js

// Dashboard.js
import React from "react";
import ProfileCard from "./ProfileCard";

function Dashboard({ user }) {
//we only receive user data to transmit again
return <ProfileCard user={user} />;
}

export default Dashboard;

4. ProfileCard.js

// ProfileCard.js
import React from "react";

function ProfileCard({ user }) {
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
<p>{user.role}</p>
</div>
);
}

export default ProfileCard;

Only the profilecard page uses user data but the Page and Dashboard components in between are there only to pass props.
If your current build is more crowded and difficult (ex: 5–6 components), you will have to pass props for each level. This is Props Hell.

How do we escape ?

1- Using state management libraries (Redux, Zustand, Jotai, Recoil)

Get Burak Demir’s stories in your inbox

Join Medium for free to get updates from this writer.

2- Using render prop or function as child pattern

<ParentComponent>
{user => <ChildComponent user={user} />}
</ParentComponent>

3- Custom state sharing with Hooks

// useUserContext.js
import { useState } from "react";

export const useUserContext = () => {
const [user, setUser] = useState({ name: "John", role: "admin" });

// return a context-like custom API
const updateRole = (newRole) => {
setUser({ ...user, role: newRole });
};

return { user, updateRole };
};

4- React Context

import React, { createContext, useContext } from "react";

const UserContext = createContext();

function App() {
const user = { name: "John", email: "johndoe@example.com", role: "admin" };

return (
<UserContext.Provider value={user}>
<Page />
</UserContext.Provider>
);
}

function Page() {
return <Dashboard />;
}

function Dashboard() {
return <ProfileCard />;
}

function ProfileCard() {
const user = useContext(UserContext);
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
<p>{user.role}</p>
</div>
);
}

How do ı use it ?

Finally, you need to convert the context providers you created and wrap your app.js/router.js file.

import React from "react";
import { useUserContext } from "./useUserContext";
import MainPage from "./MainPage";

// Custom Provider
function UserProvider({ children }) {
const userContext = useUserContext();

return children(userContext);
}

function App() {
return (
<UserProvider>
{(userContext) => <MainPage userContext={userContext} />}
</UserProvider>
);
}

export default App;

--

--