
This warning points to a state update that runs immediately inside an effect. React renders the component, runs the effect, and the effect updates state. That update causes another render, which may run the effect again. The extra render can be unnecessary, and in some cases this pattern can keep repeating.
The wording refers to React’s effect and state APIs, rather than a JavaScript language error. The supplied JavaScript documentation is useful for JavaScript topics, but it does not establish React-specific behavior. The exact warning and recommended fixes can depend on the React version and the code around it, so check the current React documentation and the warning text in your own project.
What the warning usually means
An effect is intended to synchronise a component with something outside React, such as a browser API, a subscription, a timer, or a network request. If an effect only copies or calculates data that is already available during rendering, an effect may not be needed.
For example, imagine a component that stores a filtered list in state. After rendering, an effect calculates the list and calls a state setter. React must render once with the old list and again with the calculated list. If the effect’s dependencies or update logic cause it to run repeatedly, the sequence can turn into a render loop.
Minimal example
This example shows a common pattern: storing a value that can be calculated from props.
import { useEffect, useState } from "react";
function ItemList({ items, query }) {
const [visibleItems, setVisibleItems] = useState([]);
useEffect(() => {
const nextItems = items.filter((item) =>
item.name.toLowerCase().includes(query.toLowerCase())
);
setVisibleItems(nextItems);
}, [items, query]);
return (
<ul>
{visibleItems.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
The filtered result depends only on items and query. It does not need to be stored separately just to be displayed. Calculate it during rendering instead:
function ItemList({ items, query }) {
const visibleItems = items.filter((item) =>
item.name.toLowerCase().includes(query.toLowerCase())
);
return (
<ul>
{visibleItems.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
);
}
This is an illustrative example, not a claim that it reproduces the reported warning. The exact trigger depends on the component, React version, and surrounding code.
Likely causes
- Derived data is copied into state. A value such as a filtered list, total, or display label can often be calculated from props or existing state during rendering.
- The effect updates state on every run. Check whether the effect’s dependencies change after the update, or whether the effect has no dependency list and therefore runs after every render.
- A dependency is recreated during rendering. An object, array, or function created inline may have a new identity on each render. If it is an effect dependency, that can cause the effect to run again.
- The effect copies props into local state. This can leave the state out of sync with the props and add an avoidable render. First check whether the component can use the prop directly.
- The effect is doing work that belongs in an event handler. If a user action causes a state change, update the relevant state in the handler rather than waiting for an effect to notice the change.
- A genuine external synchronisation needs an update. Some effects must update state after reading from an external source. In that case, check that the update is necessary, guarded, and correctly cleaned up where applicable.
Step-by-step diagnostic path
1. Find the effect and the state setter
Search the component for useEffect and state setter calls such as setValue. Also check helper functions called by the effect; a setter may be hidden there. Identify exactly which effect runs before the warning appears.
2. Write down what the state represents
Ask where the value comes from. If it can be computed from props and existing state, try removing the extra state and calculating the value during render. If it represents data from an external system, an effect may be appropriate.
3. Inspect the effect’s dependencies
Compare each dependency with the values read inside the effect. Look for inline objects, arrays, or functions that are recreated on every render. Do not remove dependencies just to silence a warning: that can make the effect use outdated values. Instead, simplify the effect, move stable work outside the component when suitable, or use a React-supported approach for stabilising values if the design calls for it.
4. Check whether the update is conditional
If an effect must update state, confirm that it does not issue the same update on every run without a meaningful condition. A guard can help when it reflects the actual requirement, but adding a guard to mask a dependency problem is not a reliable fix.
5. Separate user actions from synchronisation
If a button click, form submission, or selection change causes the update, handle that change in the event handler. Reserve effects for synchronising with external systems or other work that needs to happen because a rendered value changed.
6. Check the installed React version and exact message
React-specific warnings are not documented by the JavaScript reference. Check your project’s installed React version and consult the official React documentation that matches your setup. Do not assume a warning shown by one version has identical behaviour or wording in another. The supplied JavaScript reference is included below as general language documentation, not as evidence for this React warning.
Choosing a safe fix
Use the fix that matches the purpose of the state:
- For a calculated value: compute it during render. Consider memoisation only if you have a concrete performance reason and the relevant React documentation supports the approach for your version.
- For a user-triggered change: update state in the event handler.
- For external synchronisation: keep the effect, make its dependencies accurate, and ensure updates happen only when needed. Follow the current official React guidance for the specific API involved.
Avoid fixing the warning by suppressing a lint rule, deleting a dependency, or adding a broad conditional without understanding the update flow. These changes can hide stale values or leave the component out of sync.
How to verify the change
- Reproduce the original interaction in your development environment and note which component and effect are involved.
- Apply one change at a time. This makes it easier to tell whether the cause was derived state, an unstable dependency, or an unnecessary effect.
- Repeat the same interaction and check whether the warning still appears in the console.
- Test relevant changes to props, inputs, and external data. Confirm that the displayed result updates correctly, not just that the warning disappears.
- Check that subscriptions, timers, or other external resources used by an effect are handled correctly when the component’s inputs change or it is removed. Use the current React documentation for the relevant cleanup pattern.
Do not treat a quiet console as the only success condition. A change that removes the warning but displays stale data or stops synchronising correctly is not a complete fix.
Common follow-up questions
Should I put every state update in an effect?
No. If the value is derived from props or existing state, calculate it during rendering when practical. If a user action causes the update, use the event handler. Effects are for synchronising with external systems and related side effects, not for automatically moving every calculation out of render.
Can I keep the effect and add a condition?
Yes, when the condition represents a real requirement, such as updating state only when an external value has changed. But first check why the effect runs and whether the state is necessary. A condition that merely hides repeated updates can leave the underlying dependency or data-flow problem unresolved.
References
- Source issue describing the warning
- MDN JavaScript documentation (general JavaScript reference; consult the official React documentation for React-specific guidance)
Dont SPAM