react changelog


Welcome to the latest batch of updates, where we've sprinkled in some magic to make your development experience even more delightful! 🎉 Here's what's new:


New Features

  • Internal Performance Profiling with Context Bailout: Introducing unstable_useContextWithBailout! This temporary hook lets you provide a comparison function along with a Context to determine if Context propagation and rendering should bail out earlier. It's all about making those updates snappier! 🚀

  • DevTools Gets Smarter: Say hello to DevToolsInstance! This new feature helps track Server Components more effectively by distinguishing between FiberInstance (Client Components) and VirtualInstance (Server Components). Expect a smoother, more intuitive DevTools experience. 🛠️

  • Flight Logs with Owner Stacks: When replaying logs on the client, owner stacks are now enabled. This makes debugging easier by providing more context, even outside specific rendered components. 🛫

  • GH Actions for Prereleases: We've added new workflows for publishing prereleases using GitHub Actions. This ensures a seamless transition from CircleCI, keeping everything running smoothly. 🔧


Improvements

  • Abort Fizz Renders Mid-flight: You can now abort Fizz renders during their execution, preventing incomplete render states and ensuring task counting stays consistent. 🛑

  • Snappy Element Inspection in DevTools: We've ditched timers for batching bridge traffic, making Element Inspection feel much more responsive. No more sluggish interactions! ⚡

  • Resolved Props Handling: Resolved outlined props are now assigned to both the element tuple and the parsed element object, ensuring integrity and performance during rendering. 🧩


Bugfixes

  • Global Updates in Callbacks: Fixed an issue where updates to global variables within callbacks were not retained. Your global state should now behave as expected during component renders. 🌍

  • Nested Scopes in Promoted Temporaries: Ensuring that nested scopes within pruned ones are correctly visited and promoted, making the compiler more robust. 🕵️‍♂️

  • fbt Plural and Macro Bugs: Added test fixtures to address pluralization and macro property bugs in the fbt framework. This helps ensure your translations are accurate and reliable. 🌐


Chores

  • Farewell CircleCI: We've completed our migration to GitHub Actions and bid adieu to .circleci. Streamlined workflows ahead! 👋

That's a wrap on the latest updates! Dive in and enjoy the enhanced performance, smarter DevTools, and more reliable rendering. Happy coding! 😄

Included Commits

2024-08-01T15:04:56 See commit

This commit addresses performance issues in the React DevTools' Element Inspection feature by eliminating reliance on timers for batching bridge traffic and polling. The primary problem identified was that Chrome throttles looping timers, causing delays in bridge traffic and making the interaction feel sluggish. The solution implemented is to use microtasks for batching commands, which allows for a more responsive experience by avoiding artificial slowdowns. This change aligns with React's recommendation against using timers for debouncing and instead encourages a back-pressure approach to manage message sending efficiently.

Additionally, the commit revises the use of Suspense boundaries around the Element Inspection, which previously introduced unnecessary delays in displaying props due to throttled reveals. By switching to a more appropriate method of handling fast asynchronous data using useDeferredValue, the commit removes the Suspense boundary entirely. This results in a more immediate update of selection changes in the tree view, enhancing the overall responsiveness and eliminating visual flashes during updates. The changes aim to improve user experience in the DevTools interface, making it feel snappier and more intuitive.

Files changed

  • packages/react-devtools-shared/src/__tests__/inspectedElement-test.js
  • packages/react-devtools-shared/src/__tests__/setupTests.js
  • packages/react-devtools-shared/src/bridge.js
  • packages/react-devtools-shared/src/devtools/views/Components/Components.js
  • packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js
  • packages/react-devtools-shared/src/devtools/views/Components/InspectedElementErrorBoundary.js
2024-07-26T18:38:24 See commit

This commit introduces an unstable API, unstable_useContextWithBailout, aimed at internal performance profiling rather than production use. The new hook allows developers to provide a comparison function alongside a Context, which helps determine whether to skip unnecessary Context propagation and rendering. This can enhance performance by allowing for early bailouts when the Context value has not changed, thus enabling more efficient updates. The hook returns the complete Context value, similar to the existing useContext, and enables comparisons of multiple values by returning a tuple, reducing the need for additional Context consumer hooks.

The implementation is built upon previous work related to Context updates and includes test cases to validate its functionality. It serves as a tool for profiling the performance implications of Context value updates compared to the standard useContext, providing insights into rendering costs and propagation efficiency. The associated changes span multiple files within the React codebase, indicating a significant integration of this profiling feature across various components of the framework.

Files changed

  • packages/react-debug-tools/src/ReactDebugHooks.js
  • packages/react-reconciler/src/ReactFiberHooks.js
  • packages/react-reconciler/src/ReactFiberNewContext.js
  • packages/react-reconciler/src/ReactInternalTypes.js
  • packages/react-reconciler/src/__tests__/ReactContextWithBailout-test.js
  • packages/react/index.fb.js
  • packages/react/src/ReactClient.js
  • packages/react/src/ReactHooks.js
  • packages/shared/ReactFeatureFlags.js
  • packages/shared/forks/ReactFeatureFlags.native-fb.js
  • packages/shared/forks/ReactFeatureFlags.native-oss.js
  • packages/shared/forks/ReactFeatureFlags.test-renderer.js
  • packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
  • packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
  • packages/shared/forks/ReactFeatureFlags.www.js
  • scripts/error-codes/codes.json
2024-07-26T21:36:04 See commit

This commit addresses an issue in the React compiler where updates to global variables should be retained during the execution of callback functions. Specifically, it introduces a new test case to verify that changes to a global variable, renderCount, within a callback function are correctly preserved. The test input includes a functional component Foo that uses a callback to increment the renderCount, and the expected behavior is that this increment should be accurately reflected when the component is rendered.

Additionally, the commit modifies the SproutTodoFilter to include the newly identified bug, bug-update-global-in-callback, in a set of known issues. This highlights the ongoing efforts to refine the React compiler by ensuring that it correctly handles global state updates in callback scenarios, thereby improving the overall reliability of the framework.

Files changed

  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/bug-update-global-in-callback.expect.md
  • compiler/packages/snap/src/SproutTodoFilter.ts
2024-07-29T15:26:52 See commit

The commit involves the deletion of the .circleci directory, signifying the completion of the migration from CircleCI to GitHub Actions for continuous integration processes. This transition marks a significant shift in the project's workflow, as all relevant CI/CD functionalities have now been successfully moved to GitHub.

With this change, the project no longer relies on CircleCI, allowing for a streamlined development process under the GitHub ecosystem. The commit reflects a clean-up effort, reinforcing the commitment to using GitHub Actions moving forward.

Files changed

2024-07-29T15:26:52 See commit

This commit introduces two new workflows for publishing prereleases in GitHub Actions, transitioning from the previous CircleCI setup. The new workflows maintain the same functionality as their predecessors, ensuring a seamless migration. A reusable workflow, runtime_prereleases.yml, has been created, which can be triggered in two ways: through a nightly cron job that uses the current HEAD SHA and manually via the GitHub UI by providing a specific prerelease_commit_sha.

The commit adds two specific workflows: runtime_prereleases_manual.yml for manual triggering and runtime_prereleases_nightly.yml for scheduled nightly runs. Both workflows include jobs for publishing to "Canary" and "Experimental" channels, with careful orchestration to prevent npm publishing conflicts. The implementation ensures that the publishing process remains efficient and reliable, adhering to the existing release strategy while leveraging GitHub Actions' capabilities.

Files changed

  • .github/workflows/runtime_prereleases.yml
  • .github/workflows/runtime_prereleases_manual.yml
  • .github/workflows/runtime_prereleases_nightly.yml
2024-07-29T20:18:15 See commit

The recent commit titled "Allow aborting during render" addresses an issue with the Fizz rendering system in React, where aborting a render during its execution led to inconsistencies in task counting and incomplete render states. The update enhances the abort functionality, allowing developers to abort renders synchronously from within the render process itself. This change mirrors a prior implementation made for the Flight rendering system, ensuring a more robust handling of abort scenarios during rendering.

The modifications include extensive updates to the ReactDOMFizzServer tests, ensuring that various components can be aborted during their rendering phase, including those utilizing React's Suspense and lazy loading features. The commit introduces a new rendering status and adjusts the handling of errors and segment statuses to accommodate the abort functionality. This improvement aims to provide a smoother developer experience by allowing more control over render processes, particularly in scenarios where early termination is necessary.

Files changed

  • packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
  • packages/react-server/src/ReactFizzServer.js
2024-07-30T19:15:45 See commit

This commit introduces a new DevToolsInstance to manage stateful information within the React DevTools, specifically aimed at enhancing the tracking of Server Components. The update distinguishes between FiberInstance for Client Components and VirtualInstance for Server Components, although the latter is not yet actively created. The motivation behind this change is to ensure that Server Components, which do not have a stateful instance and merely represent the latest data, can still be represented separately in the DevTools UI. This allows for better selection and reference of Server Components, even when they are rendered in different slots or updated in place.

To implement this functionality, the commit proposes a structure where Virtual Instances serve the sole purpose of maintaining state in the DevTools UI. Instead of relying on a simple mapping from id to Fiber or ReactComponentInfo, which could lead to inefficiencies and inconsistencies, the new structure allocates a dedicated DevToolsInstance for each Fiber. This instance will contain additional fields for warnings, errors, and component stacks, optimizing the handling of these states while minimizing memory usage for the majority of instances that do not require them. Overall, this change is a strategic enhancement to improve the user experience within the DevTools when working with Server Components.

Files changed

  • packages/react-devtools-shared/src/backend/fiber/renderer.js
2024-07-30T19:31:32 See commit

This commit enhances the handling of resolved outlined props in React by ensuring that when the props of a React element tuple are resolved, they are also assigned to the corresponding parsed element object. Specifically, if the parent object is identified as a React element and the key corresponds to the props, the commit updates the props of the handler.value to reflect the resolved properties. This change is crucial for maintaining the integrity of the element's props throughout the rendering process, particularly in scenarios involving re-used elements.

Additionally, the commit includes extensive testing to ensure that the updated functionality works correctly in both client and server components. The tests validate that deduplication of props for re-used elements operates as expected, whether within fragments or across different chunks. This ensures that the components render correctly without duplication or loss of props, thereby improving the overall reliability and performance of React's rendering capabilities.

Files changed

  • packages/react-client/src/ReactFlightClient.js
  • packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js
2024-07-30T20:24:45 See commit

This commit introduces a series of test fixtures aimed at addressing bugs related to the handling of pluralization and macro properties in the fbt (Facebook Translation) framework. Specifically, it focuses on scenarios where multiple fbt plural calls are made, both in function calls and JSX tags. The commit adds several test cases in the form of JavaScript and TypeScript files, which demonstrate the expected behavior when using fbt for pluralization. Notably, it includes examples that highlight discrepancies in evaluator results, such as the difference between singular and plural forms when rendering text based on dynamic input values.

Additionally, the commit modifies a file to include these new test cases in a skip filter for bugs, ensuring that they are tracked and addressed in future development. This is part of a broader effort to enhance the robustness of the fbt framework by ensuring that it correctly handles pluralization in various contexts, thereby preventing potential issues in user interfaces that rely on accurate translations.

Files changed

  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-function-calls.ts
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/bug-fbt-plural-multiple-mixed-call-tag.tsx
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/fbt/repro-macro-property-not-handled.tsx
  • compiler/packages/snap/src/SproutTodoFilter.ts
2024-07-30T20:55:41 See commit

The recent commit addresses an issue in the PromoteUsedTemporaries functionality within the React compiler, specifically related to the handling of nested scopes. During debugging of issue #30536, it was discovered that the CollectPromotableTemporaries class was failing to visit unpruned scopes that were nested within pruned ones. This oversight led to identifiers within these child scopes being skipped during the promotion of temporaries, which is crucial for ensuring that all relevant identifiers are properly tracked and promoted.

To rectify this, a single line was added to the visitScope method to ensure that the instructions of the nested scope blocks are visited appropriately. Additionally, the commit includes new test fixtures that validate the expected behavior of the code, ensuring that the fix works correctly in various scenarios. Overall, the changes enhance the robustness of the React compiler by ensuring that all scopes are properly accounted for during the promotion of temporaries.

Files changed

  • compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PromoteUsedTemporaries.ts
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/renaming-jsx-tag-lowercase.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/renaming-jsx-tag-lowercase.tsx
2024-07-31T11:56:15 See commit

This commit enables the use of owner stacks on the client side when replaying logs in the React Flight framework. Since log replay occurs outside the context of specific rendered components, the commit introduces a new implementation of the getOwnerStackByComponentInfoInDev function, which has been moved to the shared/ directory for broader accessibility. This function is now utilized by both the react-server/ and react-client/ packages, allowing for a more generic handling of component information across the React ecosystem.

Additionally, the commit includes changes to the ReactFlightClient.js file to manage the current owner in development mode and to facilitate the capture of owner stack information during log replay. The modifications also extend to testing files, ensuring that the new functionality is adequately covered by tests. A follow-up task is noted, which involves implementing similar functionality in React DevTools when native tasks are unavailable, enhancing the overall debugging experience for developers using React.

Files changed

  • packages/react-client/src/ReactFlightClient.js
  • packages/react-client/src/__tests__/ReactFlight-test.js
  • packages/react-server/src/ReactFlightServer.js