Skip to content

fix(core): propagate immediate flag to to-array chain steps - #2557

Closed
ErfanBagheri404 wants to merge 1 commit into
pmndrs:nextfrom
ErfanBagheri404:fix/immediate-to-array-chain
Closed

fix(core): propagate immediate flag to to-array chain steps#2557
ErfanBagheri404 wants to merge 1 commit into
pmndrs:nextfrom
ErfanBagheri404:fix/immediate-to-array-chain

Conversation

@ErfanBagheri404

Copy link
Copy Markdown
Contributor

Summary

When immediate: true is set with an array to prop, each step in the chain should start immediately. Previously the flag was only checked in SpringValue.start(), but when to is an array, SpringValue.start() delegates to runAsync(), which did not propagate immediate to each step.

This caused the chain to animate each step sequentially instead of jumping immediately to the final value.

Changes

  • In runAsync.ts: propagate props.immediate to each step in the to array chain when it is not explicitly set on the step itself

Test plan

  • Added regression test in Controller.test.ts
  • Changeset added: @react-spring/core: patch

Links

@changeset-bot

changeset-bot Bot commented Aug 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e7aa772

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@react-spring/core Patch
@react-spring/animated Patch
@react-spring/mock-raf Patch
@react-spring/parallax Patch
@react-spring/rafz Patch
@react-spring/shared Patch
@react-spring/types Patch
@react-spring/three Patch
@react-spring/web Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@joshuaellis

Copy link
Copy Markdown
Member

Thanks for the PR. We're going to close this one, but I want to explain the reasoning clearly since the underlying request is valid.

The short version: immediate not propagating to to-array chain steps is intentional, not a bug. The supported way to apply it across a whole chain is the object syntax:

ctrl.start({ to: [{ t: 1 }, { t: 2 }], default: { immediate: true } })

This already works today and is consistent with how the async-script path (to as a function) behaves. See the note in helpers.tsimmediate, pause, and cancel are deliberately excluded from the implicit default-prop set and must be passed via default: {}.

Why we can't merge this specific change:

  1. It mutates caller-owned objects. The loop writes queueProps.immediate = true directly onto elements of the user's to array before they're spread. With memoized or module-scope step arrays (the common case), that flag persists on the reference and leaks into unrelated animations that never requested immediate.

  2. The test doesn't verify the fix. advanceUntilIdle() drives the chain to completion either way, so expect(t.get()).toBe(2) passes whether the value jumped instantly or animated over many frames. It passes against next unpatched, so it wouldn't catch a regression.

  3. It only handles immediate === true. The prop also accepts a predicate function and an array of keys; those forms would still animate step-by-step, making the behavior inconsistent.

  4. Semantics + changeset mismatch. Changing documented default-prop propagation is a behavioral change, not a patch. If we did want bare immediate to propagate, it would need to be a deliberate, consistent change across both the array and script paths and all three immediate shapes — routed through the existing defaultProps/getDefaultProps layer rather than mutating step objects.

That said — enough people keep hitting this that I don't think the answer is "read the docs." Bare immediate: true silently not applying to chain steps is a genuine footgun, and we should explore how to support it properly rather than closing the door. I'm keeping the original issue open to scope the proper fix (consistent handling across array and script to, all three immediate shapes, no caller mutation). This PR is closed only because the implementation can't ship as-is, not because the goal is wrong.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]: Immediate does not work when to is an array

2 participants