react changelog


Welcome to the latest updates! We've been hard at work squashing bugs, adding new features, and making improvements. Here's the scoop on what's new and improved:

New Features

  • Shallow Prop Diffing Experiment: Added the enableShallowPropDiffing feature flag to test simplifying object prop comparisons with === instead of deep diffing. This aims to reduce JS-side computation while sending more data to native. 🚀

  • Non-Reactive useReducer Dispatch: Updated the dispatch function from useReducer to be stable and non-reactive. This ensures better performance and stability when using useReducer. 🛠️

Improvements

  • Async Scheduling in Flight and Fizz: Updated non-legacy uses to be asynchronous using the best available macrotask scheduler. The browser now uses postMessage, Bun uses setTimeout, and the FB build also uses setTimeout. This change improves the efficiency of work scheduling. ⏳

  • Abort During Render in React Flight: Enhanced abort logic to mark currently rendering tasks as aborted, allowing the current render to emit a partially serialized model with an error reference. This prevents the entire model from being replaced by an aborted error. 🛑

  • Enhanced Stack Frames in Console Logs: Improved visibility of stack frames in console logs by prefixing owner stacks with the current stack at the console call. This helps in better debugging by showing the most important frames, like the name of the current component. 🔍

Bugfixes

  • ip Dependency Update: Addressed CVE-2024-29415 by updating the ip dependency to version 2.0.1. This improves the application's security. 🔒

  • Host Fiber Flavor Change Error: Added an error for when a hoistable component goes from an instance to a resource, specifically for <link> elements. This ensures smoother transitions between different types of host components. ⚠️

  • Fixed readTestFilter Call: Resolved an issue where yarn snap --watch was calling readTestFilter even when the filter option was not enabled. This fix ensures the command runs smoothly. 🛠️

Chores

  • Migrated to internal-ip: Upgraded from ip to internal-ip due to security concerns with ip version 2.0.1. This change ensures better security and compatibility. 🔄

That's all for now! Keep coding and stay awesome! 😎👨‍💻👩‍💻

Included Commits

2024-06-03T14:47:45 See commit

This commit addresses an error that occurs when a host fiber changes its "flavor" or semantic type. Host components can exist as regular components, singleton components, hoistable components, or resources, each with its own rules related to mounting and reconciliation. Currently, there are three fiber types used to implement these four concepts, but the commit suggests reconsidering the model and treating host components as a single fiber type with an inner implementation. This would allow for smoother transitions between different types of host components, such as transitioning between a resource and a regular component or a singleton and a hoistable instance. The commit adds an error for when a hoistable component goes from an instance to a resource, specifically for <link> elements transitioning between stylesheets with precedence.

Additionally, the commit includes changes to several files in the codebase, such as ReactFiberConfigDOM.js, ReactDOMHostComponentTransitions-test.js, ReactFiberBeginWork.js, ReactFiberCompleteWork.js, and codes.json. It modifies the logic for handling hoistable components, updates error codes related to version mismatches, and adds specific error messages for the mentioned transitions between different types of host components. The changes aim to improve the handling of host component transitions and provide more informative error messages for developers encountering these scenarios.

Files changed

  • packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js
  • packages/react-dom/src/__tests__/ReactDOMHostComponentTransitions-test.js
  • packages/react-reconciler/src/ReactFiberBeginWork.js
  • packages/react-reconciler/src/ReactFiberCompleteWork.js
  • scripts/error-codes/codes.json
2024-06-03T16:26:38 See commit

This commit aims to improve the visibility of stack frames in the console logs for React Fiber by prefixing owner stacks with the current stack at the console call. The regular stack information is hidden behind an expando, and the appended stack to logs was not showing the most important frames like the name of the current component. By including stacks only within a ReactFiberCallUserSpace call frame, most React frames can be filtered out, especially during the rendering phase. This change is crucial for filtering out React internals and ensuring that only relevant stack frames are displayed in the console logs.

The commit includes modifications to several files related to React Fiber, such as ReactCurrentFiber.js, ReactFiberCallUserSpace.js, ReactFiberComponentStack.js, and others. The changes involve adding functions to handle owner stack information, filtering out internal stack frames, and ensuring that only user space functions are included in the stack traces. The goal is to provide a more accurate and concise representation of stack frames in the console logs, particularly for debugging purposes. Additionally, the commit addresses issues with excluding React internal stack frames and aims to improve the overall visibility of stack information in the console logs for React components.

Files changed

  • packages/react-reconciler/src/ReactCurrentFiber.js
  • packages/react-reconciler/src/ReactFiberCallUserSpace.js
  • packages/react-reconciler/src/ReactFiberComponentStack.js
  • packages/react-reconciler/src/ReactFiberOwnerStack.js
  • packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js
  • packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js
  • packages/react/src/ReactSharedInternalsClient.js
  • packages/react/src/ReactSharedInternalsServer.js
  • packages/shared/consoleWithStackDev.js
  • packages/shared/forks/consoleWithStackDev.www.js
2024-06-03T23:09:58 See commit

This commit addresses an issue where the command yarn snap --watch was calling the function readTestFilter even when the filter option was not enabled, causing a problem during development. The code in compiler/packages/snap/src/runner-watch.ts was modified to only call readTestFilter if the filter option is enabled, resolving the issue and ensuring that the command runs smoothly as intended. The changes made in this commit include modifying the subscribeFilterFile function to check for the filter option before calling readTestFilter, and adjusting the makeWatchRunner function to only call readTestFilter if the filter option is enabled, otherwise setting it to null.

Overall, this commit fixes a bug in the code that was causing readTestFilter to be called unnecessarily, leading to issues with the yarn snap --watch command. By making the necessary adjustments to only call readTestFilter when the filter option is enabled, the functionality of the command is improved and the development process is made smoother and more efficient.

Files changed

  • compiler/packages/snap/src/runner-watch.ts
2024-06-05T10:17:35 See commit

This commit addresses issue #29724 by updating the ip dependency to version 2.0.1 in order to fix the CVE-2024-29415 vulnerability. The changes made in the react-devtools package.json file include modifying the version of the ip dependency from 1.1.4 to 2.0.1, with a total of 2 changes made - 1 addition and 1 deletion.

By updating the ip dependency to the latest version, the vulnerability is resolved and the application's security is improved. This update ensures that the application is protected against potential security risks associated with the previous version of the ip dependency.

Files changed

  • packages/react-devtools/package.json
2024-06-05T14:07:58 See commit

This commit adds a new feature flag called enableShallowPropDiffing to support an experiment aimed at improving performance by simplifying the comparison of object props. Currently, deep diffing is used for object props, along with custom differs for props with custom attribute configurations. The proposed change suggests using a === comparison instead of the current approach, which would reduce computation on the JavaScript side but increase the data sent to the native side. The hypothesis is that this change should have a neutral impact on performance, potentially allowing the removal of custom differs and moving closer to deleting view configs.

The commit includes modifications to the ReactNativeAttributePayloadFabric.js file, as well as updates to test cases in the ReactNativeAttributePayloadFabric-test.internal.js file. Additionally, changes are made to various ReactFeatureFlags files to introduce and define the new enableShallowPropDiffing flag. Testing was conducted with the flag set to true, resulting in failed test cases that are expected to be deleted if the experiment is deemed successful and shipped.

Files changed

  • packages/react-native-renderer/src/ReactNativeAttributePayloadFabric.js
  • packages/react-native-renderer/src/__tests__/ReactNativeAttributePayloadFabric-test.internal.js
  • packages/shared/ReactFeatureFlags.js
  • packages/shared/forks/ReactFeatureFlags.native-fb-dynamic.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
2024-06-05T18:58:12 See commit

In this commit, the ip package was upgraded to version 2.0.1 in an attempt to address a Common Vulnerabilities and Exposures (CVE) issue. However, it was discovered that version 2.0.1 also had another CVE. As a result, the decision was made to migrate to internal-ip, which is a similar small package that can be used instead. The upgrade to version 6.2.0 of internal-ip was chosen over version 7+ due to the latter being pure ECMAScript Modules (ESM).

To test this change, validation was performed to ensure that the standalone version of React DevTools works and connects to the application. Additionally, modifications were made to the package.json file and preload.js file in the React DevTools package, as well as changes to the yarn.lock file to reflect the upgrade to internal-ip and other related dependencies.

Files changed

  • packages/react-devtools/package.json
  • packages/react-devtools/preload.js
  • yarn.lock
2024-06-05T23:51:09 See commit

This commit addresses the non-reactive behavior of the dispatch function from useReducer by marking it as stable and non-reactive. The changes include modifications to various files such as Globals.ts, HIR.ts, ObjectShape.ts, and others to define and handle the useReducer and dispatch function appropriately. Additionally, new test files were added to test the behavior of the dispatch function in useReducer.

The commit also includes updates to InferReactivePlaces.ts, InferReferenceEffects.ts, PruneNonReactiveDependencies.ts, and test fixtures to ensure that mutating a value returned from useReducer is not allowed and should be updated using the dispatch function instead. The changes aim to improve the handling of the dispatch function in useReducer to maintain reactivity and stability in the application.

Files changed

  • compiler/packages/babel-plugin-react-compiler/src/HIR/Globals.ts
  • compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
  • compiler/packages/babel-plugin-react-compiler/src/HIR/ObjectShape.ts
  • compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts
  • compiler/packages/babel-plugin-react-compiler/src/Inference/InferReferenceEffects.ts
  • compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/PruneNonReactiveDependencies.ts
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.modify-useReducer-state.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.modify-useReducer-state.js
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useReducer-returned-dispatcher-is-non-reactive.expect.md
  • compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/useReducer-returned-dispatcher-is-non-reactive.js
2024-06-06T17:07:24 See commit

This commit addresses the issue of some builds of Flight and Fizz executing work synchronously, which is necessary for legacy APIs but not ideal for modern APIs. The change updates all non-legacy uses to be asynchronous using the best available macrotask scheduler. The browser now uses postMessage, Bun uses setTimeout, and the FB build also uses setTimeout. The commit required changes to tests that were relying on the synchronous nature of work in the browser builds, and a patch was added to install MessageChannel required by the browser builds to integrate with the Scheduler mock for effective use of act to flush flight and fizz work similar to how it is done on the client.

Overall, this commit aims to improve the scheduling of work in Flight and Fizz by making it asynchronous for modern APIs. By utilizing the best available macrotask scheduler and making adjustments to tests to accommodate these changes, the commit ensures that work is scheduled more efficiently and effectively, allowing the runtime to run events and unblock additional work before starting the next work loop. The use of postMessage in the browser, setTimeout in Bun, and adjustments to tests to manage timers and tasks reflect a more optimized approach to scheduling work in Flight and Fizz.

Files changed

  • packages/react-dom/src/__tests__/ReactClassComponentPropResolutionFizz-test.js
  • packages/react-dom/src/__tests__/ReactDOMFizzDeferredValue-test.js
  • packages/react-dom/src/__tests__/ReactDOMFizzForm-test.js
  • packages/react-dom/src/__tests__/ReactDOMFizzServerBrowser-test.js
  • packages/react-dom/src/__tests__/ReactDOMFizzStaticBrowser-test.js
  • packages/react-dom/src/__tests__/ReactDOMFizzStaticFloat-test.js
  • packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOM-test.js
  • packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMBrowser-test.js
  • packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMNode-test.js
  • packages/react-server-dom-turbopack/src/__tests__/ReactFlightTurbopackDOMReply-test.js
  • packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js
  • packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js
  • packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMNode-test.js
  • packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMReply-test.js
  • packages/react-server/src/ReactFlightServer.js
  • packages/react-server/src/ReactServerStreamConfigBrowser.js
  • packages/react-server/src/ReactServerStreamConfigBun.js
  • packages/react-server/src/forks/ReactServerStreamConfig.dom-fb-experimental.js
  • packages/react/src/__tests__/ReactMismatchedVersions-test.js
  • scripts/jest/patchMessageChannel.js
  • scripts/jest/patchSetImmediate.js
  • scripts/jest/setupEnvironment.js
2024-06-06T21:41:27 See commit

This commit allows for aborting during rendering in React Flight, preventing the entire model from being replaced by an aborted error when only the currently rendering task is aborted. The update to the abort logic marks the currently rendering tasks as aborted, but still allows the current render to emit a partially serialized model with an error reference in place of the current model. This change aims to support aborting from rendering synchronously, in microtasks, and in lazy initializers, although it does not specifically support aborting from proxies that might be triggered during serialization of props.

The modifications made in this commit can be seen in the ReactFlightDOM-test.js file in the react-server-dom-webpack package, the ReactFlightServer.js file in the react-server package, and the codes.json file in the scripts/error-codes directory. These changes ensure that aborting during rendering in React Flight functions more efficiently and accurately, without disrupting the entire model.

Files changed

  • packages/react-server-dom-webpack/src/__tests__/ReactFlightDOM-test.js
  • packages/react-server/src/ReactFlightServer.js
  • scripts/error-codes/codes.json