Skip to content

[DevTools] Apply component filters on initial load#392

Closed
everettbu wants to merge 4 commits into
mainfrom
sebbie/01-21-_devtools_apply_component_filters_on_initial_load
Closed

[DevTools] Apply component filters on initial load#392
everettbu wants to merge 4 commits into
mainfrom
sebbie/01-21-_devtools_apply_component_filters_on_initial_load

Conversation

@everettbu

@everettbu everettbu commented Jan 21, 2026

Copy link
Copy Markdown

Mirror of facebook/react#35587
Original author: eps1lon


The extension wasn't using the persistested filters until you made changes in the frontend. Now we're using the same approach as the hook settings which means the timings works out to be before React renders. That way we don't have to immediately throw out the devtools backend tree like we usually do when updating component filters.

The alternative would be to use the savedPreferences messages like react-devtools-inline does. react-devtools-inline approach is less complex but would come with two downsides:

  • it comes in while we're profiling when we don't support updating filters
  • it comes in after the initial mount i.e. we always reconcile the full tree twice on initial load

Storing it in the backend means data might desync but that complexity is worth avoiding the two issues above.
If we get synchronization issues in practice we can revisit.

This removes reliance on __REACT_DEVTOOLS_COMPONENT_FILTERS__ in favor of passing a sync value or Promise to initialize instead.

Test plan

  • host Components are unfiltered on reload if no Components are filtered
  • reload&profile shows host Components and doesn't throw
CleanShot.2026-01-21.at.19.40.04.mp4

@everettbu everettbu added CLA Signed React Core Team Opened by a member of the React Core Team labels Jan 21, 2026
@everettbu
everettbu force-pushed the sebbie/01-21-_devtools_apply_component_filters_on_initial_load branch from 4cba399 to f34c5b6 Compare January 21, 2026 18:24
@everettbu
everettbu marked this pull request as ready for review January 21, 2026 19:22
@greptile-apps

greptile-apps Bot commented Jan 21, 2026

Copy link
Copy Markdown

Greptile Summary

This PR refactors component filter initialization to use an explicit parameter-based approach instead of relying on a global __REACT_DEVTOOLS_COMPONENT_FILTERS__ variable. The changes update the initialization flow across all DevTools backends (core, inline, extension) to pass component filters as either a synchronous array or a Promise during hook installation.

Key improvements:

  • Filters are now applied before React renders, avoiding unnecessary tree reconciliation
  • Unified API: all backends use the same installHook signature
  • Removes reliance on implicit global state and extension-to-backend synchronization via bridge messages
  • Documentation updated with comprehensive filter specification

Notable implementation details:

  • The extension now uses a message-based coordination system between isolated worlds to pass filters
  • Promise-based initialization naturally handles async filter retrieval without blocking
  • Store now emits component filters with settings updates for proper persistence

Confidence Score: 4/5

  • This PR is safe to merge with minor consideration for promise error handling completeness
  • The PR implements a well-structured refactor with clean changes across all relevant files. The approach is architecturally sound and addresses real timing issues with the previous global variable approach. The score reflects one minor gap: the component filter promises in the fiber renderer and inline backend lack error handling (.catch()) that exists for settings promises, meaning filter initialization failures would silently fail without warning. This is a minor quality-of-life issue rather than a functional bug, as filters have sensible defaults elsewhere in the codebase.
  • packages/react-devtools-shared/src/backend/fiber/renderer.js and packages/react-devtools-inline/src/backend.js could benefit from promise error handling for consistency with the settings promise pattern.

Important Files Changed

Filename Overview
packages/react-devtools-shared/src/backend/fiber/renderer.js Fiber renderer now handles component filters via componentFiltersOrComponentFiltersPromise parameter instead of reading from window.__REACT_DEVTOOLS_COMPONENT_FILTERS__. Promise rejection is not handled - if the promise rejects, filters won't be applied but no error is logged. This is a minor issue as initialization would silently proceed with no filters.
packages/react-devtools-core/src/backend.js Updated initialize to accept componentFilters as 4th parameter and pass to installHook. Removed overrideComponentFilters bridge message sending since filters are now injected upfront. Clean implementation.
packages/react-devtools-extensions/src/contentScripts/hookSettingsInjector.js Updated to retrieve and send both hookSettings and componentFilters from chrome storage. Properly handles default filters via getDefaultComponentFilters(). Changed source name from 'react-devtools-hook-settings-injector' to 'react-devtools-settings-injector' for clarity.
packages/react-devtools-extensions/src/contentScripts/installHook.js Creates both hookSettingsPromise and componentFiltersPromise and passes them to installHook. Properly coordinates with hookSettingsInjector to resolve both promises with settings and filters. Message source name updated to match injector changes.
packages/react-devtools-shared/src/devtools/store.js Updated settingsUpdated event to emit both hookSettings and componentFilters. Removed onBridgeOverrideComponentFilters message handler. Added complex logic in setComponentFilters to handle initialization race condition where filters change before hook settings arrive. The logic is sound but slightly intricate - it adds a listener for late-arriving hookSettings if needed.

Using the localStorage from the frontend has two downsides:
- it comes in while we're profiling when we don't support updating filters
- it comes in after the initial mount i.e. we always reconcile the full tree twice on initial load

Storing it in the backend means data might desync
but that complexity is worth avoiding the two issues above.
If we get synchronization issues in practice we can revisit.
@everettbu
everettbu force-pushed the sebbie/01-21-_devtools_apply_component_filters_on_initial_load branch from 3031aae to 43a0ec0 Compare January 22, 2026 19:17

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

15 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +1520 to 1526
if (Array.isArray(componentFiltersOrComponentFiltersPromise)) {
applyComponentFilters(componentFiltersOrComponentFiltersPromise, null);
} else {
// Unfortunately this feature is not expected to work for React Native for now.
// It would be annoying for us to spam YellowBox warnings with unactionable stuff,
// so for now just skip this message...
//console.warn('⚛ DevTools: Could not locate saved component filters');

// Fallback to assuming the default filters in this case.
applyComponentFilters(getDefaultComponentFilters(), null);
componentFiltersOrComponentFiltersPromise.then(componentFilters => {
applyComponentFilters(componentFilters, null);
});
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: The promise for component filters has no error handling. If the promise rejects, filters won't be applied and no warning will be logged. This differs from the settings promise handling in hook.js which includes a .catch() with a console error. Consider adding error handling to log a warning if component filters fail to initialize.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/react-devtools-shared/src/backend/fiber/renderer.js
Line: 1520:1526

Comment:
**style:** The promise for component filters has no error handling. If the promise rejects, filters won't be applied and no warning will be logged. This differs from the settings promise handling in hook.js which includes a `.catch()` with a console error. Consider adding error handling to log a warning if component filters fail to initialize.

How can I resolve this? If you propose a fix, please make it concise.

@everettbu

Copy link
Copy Markdown
Author

Upstream PR was closed or merged. Code is synced via branch mirror.

@everettbu everettbu closed this Jan 26, 2026
@everettbu
everettbu deleted the sebbie/01-21-_devtools_apply_component_filters_on_initial_load branch January 26, 2026 10:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed React Core Team Opened by a member of the React Core Team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants