Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: facebook/react
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: b94603b9
Choose a base ref
...
head repository: facebook/react
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d85f86cf
Choose a head ref
  • 8 commits
  • 26 files changed
  • 2 contributors

Commits on May 13, 2025

  1. [DevTools] Get source location from structured callsites in prepareSt…

    …ackTrace (#33143)
    
    When we get the source location for "View source for this element" we
    should be using the enclosing function of the callsite of the child. So
    that we don't just point to some random line within the component.
    
    This is similar to the technique in #33136.
    
    This technique is now really better than the fake throw technique, when
    available. So I now favor the owner technique. The only problem it's
    only available in DEV and only if it has a child that's owned (and not
    filtered).
    
    We could implement this same technique for the error that's thrown in
    the fake throwing solution. However, we really shouldn't need that at
    all because for client components we should be able to call
    `inspect(fn)` at least in Chrome which is even better.
    sebmarkbage authored May 13, 2025
    Configuration menu
    Copy the full SHA
    997c7bc View commit details
    Browse the repository at this point in the history
  2. Reset currentEventTransitionLane after flushing sync work (#33159)

    This keeps track of the transition lane allocated for this event. I want
    to be able to use the current one within sync work flushing to know
    which lane needs its loading indicator cleared.
    
    It's also a bit weird that transition work scheduled inside sync updates
    in the same event aren't entangled with other transitions in that event
    when `flushSync` is.
    
    Therefore this moves it to reset after flushing.
    
    It should have no impact. Just splitting it out into a separate PR for
    an abundance of caution.
    
    The only thing this might affect would be if the React internals throws
    and it doesn't reset after. But really it doesn't really have to reset
    and they're all entangled anyway.
    sebmarkbage authored May 13, 2025
    Configuration menu
    Copy the full SHA
    676f087 View commit details
    Browse the repository at this point in the history
  3. [Fiber] Stash the entangled async action lane on currentEventTransiti…

    …onLane (#33188)
    
    When we're entangled with an async action lane we use that lane instead
    of the currentEventTransitionLane. Conversely, if we start a new async
    action lane we reuse the currentEventTransitionLane.
    
    So they're basically supposed to be in sync but they're not if you
    resolve the async action and then schedule new stuff in the same event.
    Then you end up with two transitions in the same event with different
    lanes.
    
    By stashing it like this we fix that but it also gives us an opportunity
    to check just the currentEventTransitionLane to see if this event
    scheduled any regular Transition updates or Async Transitions.
    sebmarkbage authored May 13, 2025
    Configuration menu
    Copy the full SHA
    0cac32d View commit details
    Browse the repository at this point in the history
  4. [Fiber] Trigger default transition indicator if needed (#33160)

    Stacked on #33159.
    
    This implements `onDefaultTransitionIndicator`.
    
    The sequence is:
    
    1) In `markRootUpdated` we schedule Transition updates as needing
    `indicatorLanes` on the root. This tracks the lanes that currently need
    an indicator to either start or remain going until this lane commits.
    2) Track mutations during any commit. We use the same hook that view
    transitions use here but instead of tracking it just per view transition
    scope, we also track a global boolean for the whole root.
    3) If a sync/default commit had any mutations, then we clear the
    indicator lane for the `currentEventTransitionLane`. This requires that
    the lane is still active while we do these commits. See #33159. In other
    words, a sync update gets associated with the current transition and it
    is assumed to be rendering the loading state for that corresponding
    transition so we don't need a default indicator for this lane.
    4) At the end of `processRootScheduleInMicrotask`, right before we're
    about to enter a new "event transition lane" scope, it is no longer
    possible to render any more loading states for the current transition
    lane. That's when we invoke `onDefaultTransitionIndicator` for any roots
    that have new indicator lanes.
    5) When we commit, we remove the finished lanes from `indicatorLanes`
    and once that reaches zero again, then we can clean up the default
    indicator. This approach means that you can start multiple different
    transitions while an indicator is still going but it won't stop/restart
    each time. Instead, it'll wait until all are done before stopping.
    
    Follow ups:
    
    - [x] Default updates are currently not enough to cancel because those
    aren't flush in the same microtask. That's unfortunate. #33186
    - [x] Handle async actions before the setState. Since these don't
    necessarily have a root this is tricky. #33190
    - [x] Disable for `useDeferredValue`. ~Since it also goes through
    `markRootUpdated` and schedules a Transition lane it'll get a default
    indicator even though it probably shouldn't have one.~ EDIT: Turns out
    this just works because it doesn't go through `markRootUpdated` when
    work is left behind.
    - [x] Implement built-in DOM version by default. #33162
    sebmarkbage authored May 13, 2025
    Configuration menu
    Copy the full SHA
    62d3f36 View commit details
    Browse the repository at this point in the history
  5. [Fiber] Always flush Default priority in the microtask if a Transitio…

    …n was scheduled (#33186)
    
    Stacked on #33160.
    
    The purpose of this is to avoid calling `onDefaultTransitionIndicator`
    when a Default priority update acts as the loading indicator, but still
    call it when unrelated Default updates happens nearby.
    
    When we schedule Default priority work that gets batched with other
    events in the same frame more or less. This helps optimize by doing less
    work. However, that batching means that we can't separate work from one
    setState from another. If we would consider all Default priority work in
    a frame when determining whether to show the default we might never show
    it in cases like when you have a recurring timer updating something.
    
    This instead flushes the Default priority work eagerly along with the
    sync work at the end of the event, if this event scheduled any
    Transition work. This is then used to determine if the default indicator
    needs to be shown.
    sebmarkbage authored May 13, 2025
    Configuration menu
    Copy the full SHA
    b480865 View commit details
    Browse the repository at this point in the history
  6. Implement Navigation API backed default indicator for DOM renderer (#…

    …33162)
    
    Stacked on #33160.
    
    By default, if `onDefaultTransitionIndicator` is not overridden, this
    will trigger a fake Navigation event using the Navigation API. This is
    intercepted to create an on-going navigation until we complete the
    Transition. Basically each default Transition is simulated as a
    Navigation.
    
    This triggers the native browser loading state (in Chrome at least). So
    now by default the browser spinner spins during a Transition if no other
    loading state is provided. Firefox and Safari hasn't shipped Navigation
    API yet and even in the flag Safari has, it doesn't actually trigger the
    native loading state.
    
    To ensures that you can still use other Navigations concurrently, we
    don't start our fake Navigation if there's one on-going already.
    Similarly if our fake Navigation gets interrupted by another. We wait
    for on-going ones to finish and then start a new fake one if we're
    supposed to be still pending.
    
    There might be other routers on the page that might listen to intercept
    Navigation Events. Typically you'd expect them not to trigger a refetch
    when navigating to the same state. However, if they want to detect this
    we provide the `"react-transition"` string in the `info` field for this
    purpose.
    sebmarkbage authored May 13, 2025
    Configuration menu
    Copy the full SHA
    5944042 View commit details
    Browse the repository at this point in the history
  7. [Fiber] Trigger default indicator for isomorphic async actions with n…

    …o root associated (#33190)
    
    Stacked on #33160, #33162, #33186 and #33188.
    
    We have a special case that's awkward for default indicators. When you
    start a new async Transition from `React.startTransition` then there's
    not yet any associated root with the Transition because you haven't
    necessarily `setState` on anything yet until the promise resolves.
    That's what `entangleAsyncAction` handles by creating a lane that
    everything entangles with until all async actions are done.
    
    If there are no sync updates before the end of the event, we should
    trigger a default indicator until either the async action completes
    without update or if it gets entangled with some roots we should keep it
    going until those roots are done.
    sebmarkbage authored May 13, 2025
    Configuration menu
    Copy the full SHA
    3a5b326 View commit details
    Browse the repository at this point in the history

Commits on May 14, 2025

  1. Delete stray file (#33199)

    Not sure where this was coming from.
    kassens authored May 14, 2025
    Configuration menu
    Copy the full SHA
    d85f86c View commit details
    Browse the repository at this point in the history
Loading