Change:
const [prevValue, setValue] = updateState(value); updateEffect( () => { <del> Scheduler.unstable_next(() => { const previousConfig = ReactCurrentBatchConfig.suspense; ReactCurrentBatchConfig.suspense = config === undefined ? null : config; try { setValue(value); } finally { ReactCurrentBatchConfig.suspense = previousConfig; } }); </del> <ins> const previousConfig = ReactCurrentBatchConfig.suspense; ReactCurrentBatchConfig.suspense = config === undefined ? null : config; try { setValue(value); } finally { ReactCurrentBatchConfig.suspense = previousConfig; } </ins> }, [value, config], ); return prevValue; } <ins> function startTransition(setPending, config, callback) { const priorityLevel = getCurrentPriorityLevel(); runWithPriority( priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel, () => { setPending(true); }, ); runWithPriority( priorityLevel > NormalPriority ? NormalPriority : priorityLevel, () => { const previousConfig = ReactCurrentBatchConfig.suspense; ReactCurrentBatchConfig.suspense = config === undefined ? null : config; try { setPending(false); callback(); } finally { ReactCurrentBatchConfig.suspense = previousConfig; } }, ); } </ins> function mountTransition( config: SuspenseConfig | void | null, ): [(() => void) => void, boolean] { const [isPending, setPending] = mountState(false); <del> const startTransition = mountCallback( callback => { setPending(true); Scheduler.unstable_next(() => { const previousConfig = ReactCurrentBatchConfig.suspense; ReactCurrentBatchConfig.suspense = config === undefined ? null : config; try { setPending(false); callback(); } finally { ReactCurrentBatchConfig.suspense = previousConfig; } }); }, [config, isPending], ); return [startTransition, isPending]; </del> <ins> const start = mountCallback(startTransition.bind(null, setPending, config), [ setPending, config, ]); return [start, isPending]; </ins> } function updateTransition( config: SuspenseConfig | void | null, ): [(() => void) => void, boolean] { const [isPending, setPending] = updateState(false); <del> const startTransition = updateCallback( callback => { setPending(true); Scheduler.unstable_next(() => { const previousConfig = ReactCurrentBatchConfig.suspense; ReactCurrentBatchConfig.suspense = config === undefined ? null : config; try { setPending(false); callback(); } finally { ReactCurrentBatchConfig.suspense = previousConfig; } }); }, [config, isPending], ); return [startTransition, isPending]; </del> <ins> const start = updateCallback(startTransition.bind(null, setPending, config), [ setPending, config, ]); return [start, isPending]; </ins> } function dispatchAction<S, A>(

Discussion:
Do you want to request a feature or report a bug? Bug What is the current behavior? is never set to true when calling within , but it does work properly when within a . Here's the correct behavior (accomplished via ): ! Here's the incorrect behavior (via ): ! Note the difference is that the opacity never changes to 0.4 (which is determined based on the state). What is the expected behavior? I expect them to both behave the same (at least as far as the user can observe). Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React? react react-dom
I guess startTransition is never intended to be used in effects. I didn't expect it even works. Looking at the doc again, Hmm, it doesn't clearly say so.
Ok but the use cases is interesting.
Do you think this is the same as
Yes, I believe that's the same issue.
Hello, I think I have a similar issue when using with . When returns a new value I would like to create a new resource. I tried to use for this, but I don't even have an idea where to put ...
you can see the isPending is if the is bigger than 5100 when calling in .
I'm seeing the same behavior as - setting to a value of 5200 or higher causes to fire reliably in the original CodeSandbox:
That is a bug we need to fix regardless.
Fixed by . Updated Sandbox: