How to fix startTransition requires at least one state update inside its function in React
This React 18 error occurs when you call startTransition with a callback that does not perform any state updates. startTransition is designed to mark state updates as low-priority transitions, so it expects at least one setState call within its callback function.
Quick fix
Fixes startTransition requires at least one state update inside its function
import { startTransition, useState } from 'react';
function SearchComponent() {
const [query, setQuery] = useState('');
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// ❌ WRONG - no state update inside startTransition
startTransition(() => {
console.log('Searching...');
});
// ✅ CORRECT - state update is inside startTransition
startTransition(() => {
setQuery(e.target.value);
});
};
return <input onChange={handleChange} />;
}- Verify the startTransition callback contains a state update
- Move state updates from outside into the callback
- Remove startTransition if no state update is needed
- Handle conditional state updates properly
import { startTransition, useState } from 'react';function SearchComponent() {const [query, setQuery] = useState('');const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {// ❌ WRONG - no state update inside startTransitionstartTransition(() => {console.log('Searching...');});// ✅ CORRECT - state update is inside startTransitionstartTransition(() => {setQuery(e.target.value);});};return <input onChange={handleChange} />;}startTransition requires at least one state update inside its function
What this error means
This error appears when you use React 18's startTransition API with a callback function that doesn't actually trigger any state updates. The startTransition function is specifically designed to mark state updates as non-urgent "transitions" that can be interrupted by more critical updates, improving the user experience during expensive operations. React expects startTransition to wrap actual state changes (via useState's setter, useReducer's dispatch, or similar). If you pass a callback that doesn't contain any state update calls, React throws this error because there's no transition to perform. This is different from other React hooks where an empty callback might simply do nothing—startTransition validates that it's being used for its intended purpose. The error serves as a safeguard against misusing the API, such as wrapping non-state-updating logic or forgetting to include the actual setState call within the transition callback.
Typical symptoms
- Error appears in console: "startTransition requires at least one state update inside its function"
- Application crashes or throws runtime error when startTransition is called
- State updates outside startTransition work normally, but wrapped calls fail
- Error occurs during component initialization or event handling
Common causes
- Calling startTransition with an empty callback function
- Placing state update logic outside the startTransition callback
- Using startTransition to wrap non-state-updating operations like API calls or logging
- Moving setState call into a nested setTimeout or Promise without proper wrapping
- Conditionally skipping all state updates inside the transition callback
- Incorrectly refactoring code and accidentally removing the setState call
How to fix "startTransition requires at least one state update inside its function"
Check that your startTransition callback actually calls a state setter function:
import { startTransition, useState } from 'react';
function SearchComponent() {
const [query, setQuery] = useState('');
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// ❌ WRONG - no state update inside startTransition
startTransition(() => {
console.log('Searching...');
});
// ✅ CORRECT - state update is inside startTransition
startTransition(() => {
setQuery(e.target.value);
});
};
return <input onChange={handleChange} />;
}Make sure the setState (or dispatch) call is directly inside the callback.
If your state update is happening outside the startTransition callback, move it inside:
// ❌ WRONG - state update outside transition
startTransition(() => {
// Empty callback
});
setResults(newResults);
// ✅ CORRECT - state update inside transition
startTransition(() => {
setResults(newResults);
});Only non-state operations (like measurements or calculations) should happen outside.
If you're not actually updating state, don't use startTransition:
// ❌ WRONG - startTransition with no state update
startTransition(() => {
console.log('Logging something');
trackAnalytics('event');
});
// ✅ CORRECT - just call the function directly
console.log('Logging something');
trackAnalytics('event');startTransition is only for marking state updates as transitions, not general function calls.
If your state update is conditional, ensure at least one branch updates state or remove startTransition:
// ❌ WRONG - might execute with no state update
startTransition(() => {
if (someCondition) {
setData(newData);
}
// If someCondition is false, no state update occurs
});
// ✅ OPTION 1 - Ensure state update always happens
startTransition(() => {
if (someCondition) {
setData(newData);
} else {
setData(defaultData); // Always update
}
});
// ✅ OPTION 2 - Move startTransition inside conditional
if (someCondition) {
startTransition(() => {
setData(newData);
});
}Choose the pattern that matches your intent.
For state updates inside async operations, wrap each update in its own startTransition:
// ❌ WRONG - async function as callback (React 18)
startTransition(async () => {
const data = await fetchData();
setData(data); // This won't be marked as transition
});
// ✅ CORRECT - Wrap the state update after async
const handleClick = async () => {
const data = await fetchData();
startTransition(() => {
setData(data); // Marked as transition
});
};
// Note: React 19 supports async startTransition directlyIn React 18, startTransition callbacks must be synchronous.
Advanced notes
React 19 Improvements: In React 19, startTransition supports async functions natively, so you can use async/await inside the callback without manual wrapping. The requirement for synchronous callbacks was a React 18 limitation.
useTransition Alternative: If you need to show loading states during transitions, use the useTransition hook instead: const [isPending, startTransition] = useTransition();. This provides an isPending flag you can use to display loading UI.
Transition Scope: Only state updates called directly during the execution of the startTransition callback are marked as transitions. Updates in nested timeouts, promises, or event handlers need their own startTransition wrappers.
Performance Consideration: Don't wrap every state update in startTransition—only use it for updates that can be deferred (like filtering large lists or updating search results). Urgent updates (like text input in a controlled component) should remain synchronous.
Debugging Tip: If you're unsure whether your callback is executing, add a console.log immediately before the setState call to verify it's being reached. The error only triggers if React detects zero state updates during callback execution.
Frequently asked questions
- What does "startTransition requires at least one state update inside its function" mean?
- This error appears when you use React 18's startTransition API with a callback function that doesn't actually trigger any state updates. The startTransition function is specifically designed to mark state updates as non-urgent "transitions" that can be interrupted by more critical updates, improving the user experience during expensive operations. React expects startTransition to wrap actual state changes (via useState's setter, useReducer's dispatch, or similar).
- How do I fix "startTransition requires at least one state update inside its function"?
- This React 18 error occurs when you call startTransition with a callback that does not perform any state updates. startTransition is designed to mark state updates as low-priority transitions, so it expects at least one setState call within its callback function.
- What causes "startTransition requires at least one state update inside its function"?
- Calling startTransition with an empty callback function Placing state update logic outside the startTransition callback Using startTransition to wrap non-state-updating operations like API calls or logging
- Is the "startTransition requires at least one state update inside its function" error serious?
- It is a low-severity error — more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- 📚React Official Documentation
- 📖React startTransition API documentation(Official Docs)
- 📖React useTransition hook documentation(Official Docs)
- 🐙