[DevTools] Only schedule a single update per Supense when changing timeline#633
Conversation
Greptile SummaryThis PR fixes a crash when DevTools manages multiple React renderers (e.g., React canary + React experimental) by scoping Suspense milestone updates to the correct renderer instead of broadcasting to all renderers. Each
Confidence Score: 4/5
Important Files Changed
Last reviewed commit: 2bf26ec |
| const renderer = ((this._rendererInterfaces[ | ||
| (rendererID: any) | ||
| ]: any): RendererInterface); | ||
| if (renderer.supportsTogglingSuspense) { |
There was a problem hiding this comment.
Missing null check for renderer lookup
Every other renderer lookup in this class (e.g., overrideSuspense at line 782, overrideError at line 770, logElementToConsole at line 757) guards against an invalid rendererID with a renderer == null check and a console.warn. This method skips that check and instead casts the result directly to RendererInterface, then immediately accesses renderer.supportsTogglingSuspense. If the rendererID is invalid or the renderer was unregistered, this will throw a TypeError instead of gracefully warning.
| const renderer = ((this._rendererInterfaces[ | |
| (rendererID: any) | |
| ]: any): RendererInterface); | |
| if (renderer.supportsTogglingSuspense) { | |
| const renderer = this._rendererInterfaces[rendererID]; | |
| if (renderer == null) { | |
| console.warn(`Invalid renderer id "${rendererID}"`); | |
| } else if (renderer.supportsTogglingSuspense) { |
Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/react-devtools-shared/src/backend/agent.js
Line: 794-797
Comment:
**Missing null check for renderer lookup**
Every other renderer lookup in this class (e.g., `overrideSuspense` at line 782, `overrideError` at line 770, `logElementToConsole` at line 757) guards against an invalid `rendererID` with a `renderer == null` check and a `console.warn`. This method skips that check and instead casts the result directly to `RendererInterface`, then immediately accesses `renderer.supportsTogglingSuspense`. If the `rendererID` is invalid or the renderer was unregistered, this will throw a `TypeError` instead of gracefully warning.
```suggestion
const renderer = this._rendererInterfaces[rendererID];
if (renderer == null) {
console.warn(`Invalid renderer id "${rendererID}"`);
} else if (renderer.supportsTogglingSuspense) {
```
How can I resolve this? If you propose a fix, please make it concise.|
Upstream PR was closed or merged. Code is synced via branch mirror. |
Mirror of facebook/react#35927
Original author: eps1lon
Changing the Suspense timeline milestone was brute force. We sent the Fiber to each renderer for update. Not only is that wasteful, it can also break React if the Fibers from one renderer were not compatible with another renderer.
E.g. scheduling an update on a Fiber from React canary with React experimental would crash. Instead of
pendingIndicatorbeingnull | () => {}, React would seeundefinedsincependingIndicatorsimply doesn't exist in React canary.Test plan
Before:
CleanShot.2026-02-28.at.17.02.27.mp4
After:
CleanShot.2026-02-28.at.16.59.45.mp4