Debugging React applications has been a big part of my daily work for more than a decade. Over the years, I’ve seen many errors, but one that often confuses developers is:
“Warning: Cannot update a component while rendering a different component.”
When I first came across this, I was working on a dashboard for a U.S. retail client. The app had multiple forms, charts, and authentication flows. Suddenly, this warning popped up, and my console was flooded with yellow messages.
In this tutorial, I’ll walk you through why this happens and, more importantly, how to fix it. I’ll share multiple methods along with full working code examples. Each method has a short explanation below it, so you can apply the fix immediately.
What Does This Warning Mean?
This warning appears when you try to update a state in one component while React is still rendering another component.
React’s rendering process is strict. It doesn’t allow you to modify state or trigger updates in the middle of rendering another component. Doing so can cause inconsistent UI and broken renders.
For example:
- Updating the parent state directly while rendering a child.
- Triggering setState inside the render body.
- Calling navigation or context updates during render.
Method 1: Move State Updates to useEffect
One of the most common causes is calling setState directly during rendering. Instead, you should move the update into a useEffect hook.
Example
import React, { useState, useEffect } from "react";
function Register({ onRegister }) {
const [registered, setRegistered] = useState(false);
// Wrong: This would cause the warning if placed inside render
// if (!registered) {
// setRegistered(true);
// onRegister();
// }
// Correct: Move state update into useEffect
useEffect(() => {
if (!registered) {
setRegistered(true);
onRegister();
}
}, [registered, onRegister]);
return <div>Registering user...</div>;
}
function App() {
const [status, setStatus] = useState("Not Registered");
const handleRegister = () => {
setStatus("Registered Successfully");
};
return (
<div>
<h1>{status}</h1>
<Register onRegister={handleRegister} />
</div>
);
}
export default App;I executed the above example code and added the screenshot below.

Here, instead of calling setRegistered inside the render body, I moved it into a useEffect. This ensures the update only happens after the render cycle completes.
Method 2: Use a Callback Instead of Direct State Updates
Sometimes, the issue comes from updating the parent state directly from a child during render. The fix is to use a callback function passed as a prop.
Example
import React, { useState } from "react";
function Child({ notifyParent }) {
// Wrong: Directly updating parent during render would cause the warning
// notifyParent("Child is ready");
// Correct: Trigger parent update on an event (like button click)
return (
<button onClick={() => notifyParent("Child is ready")}>
Notify Parent
</button>
);
}
function App() {
const [message, setMessage] = useState("Waiting...");
return (
<div>
<h2>{message}</h2>
<Child notifyParent={setMessage} />
</div>
);
}
export default App;I executed the above example code and added the screenshot below.

Instead of calling setMessage during render, I only call it when the button is clicked. This avoids the warning and keeps the app predictable.
Method 3: Use Context the Right Way
If you’re using React Context, you might accidentally update context inside render. The fix is to update context values inside an event or effect.
Example
import React, { useState, useContext, createContext, useEffect } from "react";
const AuthContext = createContext();
function AuthProvider({ children }) {
const [user, setUser] = useState(null);
const login = (name) => {
setUser({ name });
};
return (
<AuthContext.Provider value={{ user, login }}>
{children}
</AuthContext.Provider>
);
}
function LoginForm() {
const { user, login } = useContext(AuthContext);
useEffect(() => {
if (!user) {
login("John Doe"); // Safe inside useEffect
}
}, [user, login]);
return <div>{user ? `Welcome ${user.name}` : "Logging in..."}</div>;
}
function App() {
return (
<AuthProvider>
<LoginForm />
</AuthProvider>
);
}
export default App;I executed the above example code and added the screenshot below.

Here, I call the login inside useEffect instead of directly in the render body. This ensures the context update happens after rendering.
Method 4: Avoid Conditional State Updates in Render
Another common mistake is conditionally setting state during render. The correct approach is to compute values or use useMemo.
Example
import React, { useState, useMemo } from "react";
function ScoreBoard({ scores }) {
const [highlight, setHighlight] = useState(null);
// Wrong: Directly setting state during render
// if (scores.length > 5) {
// setHighlight("High Activity");
// }
// Correct: Use useMemo to compute derived state
const highlightText = useMemo(() => {
return scores.length > 5 ? "High Activity" : "Normal";
}, [scores]);
return (
<div>
<h3>Scores: {scores.join(", ")}</h3>
<p>Status: {highlightText}</p>
</div>
);
}
function App() {
return <ScoreBoard scores={[10, 20, 30, 40, 50, 60]} />;
}
export default App;Instead of calling setHighlight during render, I used useMemo to calculate the derived value. This avoids unnecessary state updates.
Method 5: Use useLayoutEffect for Immediate Updates
In rare cases, you may need to update the state immediately after DOM mutations. Instead of doing it in render, use useLayoutEffect.
Example
import React, { useState, useLayoutEffect, useRef } from "react";
function AutoFocusInput() {
const [focused, setFocused] = useState(false);
const inputRef = useRef();
useLayoutEffect(() => {
if (!focused) {
inputRef.current.focus();
setFocused(true);
}
}, [focused]);
return <input ref={inputRef} placeholder="Type here..." />;
}
function App() {
return (
<div>
<h2>Auto Focus Example</h2>
<AutoFocusInput />
</div>
);
}
export default App;Here, I used useLayoutEffect to focus the input right after render. This ensures the DOM is updated before React paints the screen.
- Never call setState inside the render body.
- Use useEffect or useLayoutEffect for updates after render.
- Pass callbacks to children instead of updating parent state directly.
- Use useMemo for derived values instead of conditional state updates.
- Keep context updates outside of render logic.
I’ve personally run into this React warning many times, especially while building large-scale apps for U.S. clients in finance and retail. The fix always comes down to the same principle:
Don’t trigger updates during render.
If you follow the methods I’ve shared, moving updates into useEffect, using callbacks, handling context properly, and avoiding conditional state updates, you’ll never see this warning again.
You may also read:
- React Pagination Component Examples
- Ways to Add a React Code Editor Component
- React Component Folder Structure Best Practices
- Use react-vertical-timeline-component in React

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.