Blocks #14845.
Describe the bug
Turning on StrictMode gives a bunch of errors, this is a tracking ticket to list them out.
I'll list one per comment, along with an e2e test that generates the error.
To reproduce
Run the e2e tests with SCRIPT_DEBUG set to true.
Test: npm run test-e2e packages/e2e-tests/specs/links.test.js
Links › can be created by selecting text and using keyboard shortcuts
expect(jest.fn()).not.toHaveErrored(expected)
Expected mock function not to be called but it was called with:
["Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s the componentWillUnmount method
in URLInput
in Unknown (created by WithSelect(URLInput))
in WithSelect(URLInput) (created by WithInstanceId(WithSelect(URLInput)))
in WithInstanceId(WithSelect(URLInput)) (created by WithSpokenMessages(WithInstanceId(WithSelect(URLInput))))
in WithSpokenMessages(WithInstanceId(WithSelect(URLInput))) (created by WithSafeTimeout(WithSpokenMessages(WithInstanceId(WithSelect(URLInput)))))
in WithSafeTimeout(WithSpokenMessages(WithInstanceId(WithSelect(URLInput)))) (created by LinkEditor)
in form (created by LinkEditor)
in LinkEditor (created by InlineLinkUI)
in div (created by URLPopover)
in div (created by URLPopover)
in div (created by Animate)
in div (created by IsolatedEventContainer)
in IsolatedEventContainer (created by Animate)
in Animate (created by Popover)
in PopoverDetectOutside (created by WithFocusOutside(PopoverDetectOutside))
in div (created by WithFocusOutside(PopoverDetectOutside))
in WithFocusOutside(PopoverDetectOutside) (created by Popover)
in Unknown (created by FocusReturn)
in div (created by FocusReturn)
in FocusReturn (created by Context.Consumer)
in WithFocusReturn(Component) (created by WithConstrainedTabbing(WithFocusReturn(Component)))
in div (created by WithConstrainedTabbing(WithFocusReturn(Component)))
in WithConstrainedTabbing(WithFocusReturn(Component)) (created by Popover)"]
Test: npm run test-e2e packages/e2e-tests/specs/reusable-blocks.test.js
Reusable Blocks › can be created
expect(jest.fn()).not.toHaveErrored(expected)
Expected mock function not to be called but it was called with:
["Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s the componentWillUnmount method
in SlotComponent (created by Context.Consumer)
in Slot (created by __experimentalBlockSettingsMenuPluginsExtensionSlot)
in __experimentalBlockSettingsMenuPluginsExtensionSlot (created by Dropdown)
in div (created by MenuGroup)
in div (created by MenuGroup)
in MenuGroup (created by WithInstanceId(MenuGroup))
in WithInstanceId(MenuGroup) (created by Dropdown)
in div (created by NavigableContainer)
in NavigableContainer (created by ForwardRef(NavigableContainer))
in ForwardRef(NavigableContainer) (created by ForwardRef(NavigableMenu))
in ForwardRef(NavigableMenu) (created by Dropdown)
in div (created by Animate)
in div (created by IsolatedEventContainer)
in IsolatedEventContainer (created by Animate)
in Animate (created by Popover)
in PopoverDetectOutside (created by WithFocusOutside(PopoverDetectOutside))
in div (created by WithFocusOutside(PopoverDetectOutside))
in WithFocusOutside(PopoverDetectOutside) (created by Popover)
in Unknown (created by FocusReturn)
in div (created by FocusReturn)
in FocusReturn (created by Context.Consumer)
in WithFocusReturn(Component) (created by WithConstrainedTabbing(WithFocusReturn(Component)))
in div (created by WithConstrainedTabbing(WithFocusReturn(Component)))
in WithConstrainedTabbing(WithFocusReturn(Component)) (created by Popover)
in FillComponent (created by Context.Consumer)
in Fill (created by Context.Consumer)
in span (created by Context.Consumer)
in Popover (created by Dropdown)
in div (created by Dropdown)
in Dropdown (created by DropdownMenu)
in DropdownMenu (created by BlockActions)
in div (created by ToolbarContainer)
in ToolbarContainer (created by Toolbar)
in Toolbar (created by BlockActions)
in BlockActions (created by WithDispatch(BlockActions))
in WithDispatch(BlockActions)
in Unknown (created by WithSelect(WithDispatch(BlockActions)))
in WithSelect(WithDispatch(BlockActions)) (created by BlockSettingsMenu)
in BlockSettingsMenu (created by BlockToolbar)
in div (created by BlockToolbar)
in BlockToolbar
in Unknown (created by WithSelect(BlockToolbar))
in WithSelect(BlockToolbar) (created by BlockContextualToolbar)
in div (created by NavigableContainer)
in NavigableContainer (created by ForwardRef(NavigableContainer))
in ForwardRef(NavigableContainer) (created by ForwardRef(NavigableMenu))
in ForwardRef(NavigableMenu) (created by NavigableToolbar)
in NavigableToolbar (created by BlockContextualToolbar)
in BlockContextualToolbar (created by BlockListBlock)
in div (created by BlockListBlock)
in div (created by ForwardRef)
in ForwardRef (created by IgnoreNestedEvents)
in IgnoreNestedEvents (created by ForwardRef(IgnoreNestedEvents))
in ForwardRef(IgnoreNestedEvents) (created by BlockListBlock)
in BlockListBlock
in Unknown
in Unknown (created by (BlockListBlock))
in (BlockListBlock) (created by WithFilters(BlockListBlock))
in WithFilters(BlockListBlock) (created by IfCondition(WithFilters(BlockListBlock)))
in IfCondition(WithFilters(BlockListBlock)) (created by WithDispatch(IfCondition(WithFilters(BlockListBlock))))
in WithDispatch(IfCondition(WithFilters(BlockListBlock)))
in Unknown (created by WithSelect(WithDispatch(IfCondition(WithFilters(BlockListBlock)))))
in WithSelect(WithDispatch(IfCondition(WithFilters(BlockListBlock))))
in Unknown (created by Pure(WithViewportMatch(WithSelect(WithDispatch(IfCondition(WithFilters(BlockListBlock)))))))
in Pure(WithViewportMatch(WithSelect(WithDispatch(IfCondition(WithFilters(BlockListBlock)))))) (created by BlockList)
in BlockAsyncModeProvider (created by BlockList)"]
(I don't know if the SlotComponent errors are all the same thing, or different things with similar symptoms, so posting them all.)
Test: npm run test-e2e packages/e2e-tests/specs/table.test.js
Table › allows header and footer rows to be switched on and off
expect(jest.fn()).not.toHaveErrored(expected)
Expected mock function not to be called but it was called with:
["Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in %s.%s the componentWillUnmount method
in SlotComponent (created by Context.Consumer)
in Slot (created by FormatToolbar)
in div (created by ToolbarContainer)
in ToolbarContainer (created by Toolbar)
in Toolbar (created by FormatToolbar)
in div (created by FormatToolbar)
in FormatToolbar (created by RichText)
in FillComponent (created by Context.Consumer)
in Fill (created by BlockFormatControlsFill)
in BlockFormatControlsFill (created by Context.Consumer)
in IfBlockEditSelected(BlockFormatControlsFill) (created by RichText)"]
Test: npm run test-e2e packages/e2e-tests/specs/plugins/meta-attribute-block.test.js
Block with a meta attribute › Should persist the meta attribute properly
expect(jest.fn()).not.toHaveErrored(expected)
Expected mock function not to be called but it was called with:
["Warning: A component is changing an uncontrolled input of type %s to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s undefined
in input (created by edit)
in edit (created by Edit)
in Edit (created by WithToolbarControls(Edit))
in WithToolbarControls(Edit) (created by WithInspectorControl(WithToolbarControls(Edit)))
in WithInspectorControl(WithToolbarControls(Edit)) (created by WithInspectorControl(WithInspectorControl(WithToolbarControls(Edit))))
in WithInspectorControl(WithInspectorControl(WithToolbarControls(Edit)))
in Unknown (created by WithDispatch(Component))
in WithDispatch(Component)
in Unknown (created by WithMultipleValidation(WithInspectorControl(WithInspectorControl(WithToolbarControls(Edit)))))
in WithMultipleValidation(WithInspectorControl(WithInspectorControl(WithToolbarControls(Edit)))) (created by WithFilters(Edit))
in WithFilters(Edit) (created by BlockEdit)
in BlockEdit (created by BlockListBlock)
in BlockCrashBoundary (created by BlockListBlock)
in div (created by IgnoreNestedEvents)
in IgnoreNestedEvents (created by ForwardRef(IgnoreNestedEvents))
in ForwardRef(IgnoreNestedEvents) (created by BlockListBlock)
in div (created by BlockListBlock)
in div (created by ForwardRef)
in ForwardRef (created by IgnoreNestedEvents)
in IgnoreNestedEvents (created by ForwardRef(IgnoreNestedEvents))
in ForwardRef(IgnoreNestedEvents) (created by BlockListBlock)
in BlockListBlock
in Unknown
in Unknown (created by (BlockListBlock))
in (BlockListBlock) (created by WithFilters(BlockListBlock))
in WithFilters(BlockListBlock) (created by IfCondition(WithFilters(BlockListBlock)))
in IfCondition(WithFilters(BlockListBlock)) (created by WithDispatch(IfCondition(WithFilters(BlockListBlock))))
in WithDispatch(IfCondition(WithFilters(BlockListBlock)))
in Unknown (created by WithSelect(WithDispatch(IfCondition(WithFilters(BlockListBlock)))))
in WithSelect(WithDispatch(IfCondition(WithFilters(BlockListBlock))))
in Unknown (created by Pure(WithViewportMatch(WithSelect(WithDispatch(IfCondition(WithFilters(BlockListBlock)))))))
in Pure(WithViewportMatch(WithSelect(WithDispatch(IfCondition(WithFilters(BlockListBlock)))))) (created by BlockList)
in BlockAsyncModeProvider (created by BlockList)
in div (created by BlockList)
in BlockList (created by WithDispatch(BlockList))
in WithDispatch(BlockList)
in Unknown (created by WithSelect(WithDispatch(BlockList)))
in WithSelect(WithDispatch(BlockList))
in Unknown (created by VisualEditor)
in div (created by CopyHandler)
in CopyHandler (created by WithDispatch(CopyHandler))
in WithDispatch(CopyHandler) (created by VisualEditor)
in div (created by ObserveTyping)
in ObserveTyping (created by WithSafeTimeout(ObserveTyping))
in WithSafeTimeout(ObserveTyping) (created by WithDispatch(WithSafeTimeout(ObserveTyping)))
in WithDispatch(WithSafeTimeout(ObserveTyping))
in Unknown (created by WithSelect(WithDispatch(WithSafeTimeout(ObserveTyping))))
in WithSelect(WithDispatch(WithSafeTimeout(ObserveTyping))) (created by VisualEditor)
in div (created by WritingFlow)
in div (created by WritingFlow)
in WritingFlow (created by WithDispatch(WritingFlow))
in WithDispatch(WritingFlow)
in Unknown (created by WithSelect(WithDispatch(WritingFlow)))
in WithSelect(WithDispatch(WritingFlow)) (created by VisualEditor)
in div (created by Typewriter)
in Typewriter
in Unknown (created by WithSelect(Typewriter))
in WithSelect(Typewriter) (created by VisualEditor)
in div (created by BlockSelectionClearer)
in BlockSelectionClearer (created by WithDispatch(BlockSelectionClearer))
in WithDispatch(BlockSelectionClearer)
in Unknown (created by WithSelect(WithDispatch(BlockSelectionClearer)))
in WithSelect(WithDispatch(BlockSelectionClearer)) (created by VisualEditor)
in VisualEditor (created by Layout)
in div (created by Layout)
in div (created by FocusReturnProvider)
in FocusReturnProvider (created by Layout)
in Layout
in Unknown (created by WithViewportMatch(Layout))
in WithViewportMatch(Layout) (created by NavigateRegions(WithViewportMatch(Layout)))
in div (created by NavigateRegions(WithViewportMatch(Layout)))
in NavigateRegions(WithViewportMatch(Layout)) (created by WithDispatch(NavigateRegions(WithViewportMatch(Layout))))
in WithDispatch(NavigateRegions(WithViewportMatch(Layout)))
in Unknown (created by WithSelect(WithDispatch(NavigateRegions(WithViewportMatch(Layout)))))
in WithSelect(WithDispatch(NavigateRegions(WithViewportMatch(Layout)))) (created by Editor)
in ErrorBoundary (created by Editor)
in BlockEditorProvider (created by WithDispatch(BlockEditorProvider))
in WithDispatch(BlockEditorProvider)
in Unknown (created by Context.Consumer)
in WithRegistryProvider(WithDispatch(BlockEditorProvider)) (created by EditorProvider)
in EditorProvider (created by WithDispatch(EditorProvider))
in WithDispatch(EditorProvider)
in Unknown (created by WithSelect(WithDispatch(EditorProvider)))
in WithSelect(WithDispatch(EditorProvider))
in Unknown (created by Context.Consumer)
in WithRegistryProvider(WithSelect(WithDispatch(EditorProvider))) (created by Editor)
in div (created by DropZoneProvider)
in DropZoneProvider (created by Editor)
in SlotFillProvider (created by Editor)
in StrictMode (created by Editor)
in Editor (created by WithDispatch(Editor))
in WithDispatch(Editor)
in Unknown (created by WithSelect(WithDispatch(Editor)))
in WithSelect(WithDispatch(Editor))"]
Test: npm run test-e2e packages/e2e-tests/specs/datepicker.test.js
Datepicker › should show the publishing date if the date is in the past
expect(jest.fn()).not.toHaveErrored(expected)
Expected mock function not to be called but it was called with:
["Warning: Unsafe lifecycle methods were found within a strict-mode tree:%s
%s
Learn more about this warning here:
https://fb.me/react-strict-mode-warnings
in StrictMode (created by Editor)
in Editor (created by WithDispatch(Editor))
in WithDispatch(Editor)
in Unknown (created by WithSelect(WithDispatch(Editor)))
in WithSelect(WithDispatch(Editor)) componentWillReceiveProps: Please update the following components to use static getDerivedStateFromProps instead: CalendarMonth, CalendarMonthGrid, DayPicker, DayPickerSingleDateController, OutsideClickHandler
componentWillUpdate: Please update the following components to use componentDidUpdate instead: DayPicker, DayPickerSingleDateController"],["Warning: Legacy context API has been detected within a strict-mode tree: %s
Please update the following components: %s
Learn more about this warning here:
https://fb.me/react-strict-mode-warnings
in StrictMode (created by Editor)
in Editor (created by WithDispatch(Editor))
in WithDispatch(Editor)
in Unknown (created by WithSelect(WithDispatch(Editor)))
in WithSelect(WithDispatch(Editor)) withStyles(CalendarDay), withStyles(CalendarMonth), withStyles(CalendarMonthGrid), withStyles(DayPicker), withStyles(DayPickerNavigation)"]
@pento
I'm seeing these (or possibly related) errors when using a RichText component inside the edit() method of a custom block.
It looks like the errors are coming from the Toolbar components on the RichText control, but I'm not positive.
I've been trying to figure out if I'm doing something wrong (ie trying to mount the components on an unmounted component) but I'm really not a React expert (yet) and I don't know exactly what this means or how to debug it further.
Is this something that's actually coming from a core package or, if this is on me, do you have any advice or recommendations for me on either where to look to learn more about how to do this properly?
Thanks!
Full error (in case it helps):
react-dom.js?ver=16.9.0:539 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in SlotComponent (created by Context.Consumer)
in Slot (created by FormatToolbar)
in div (created by ToolbarContainer)
in ToolbarContainer (created by Toolbar)
in Toolbar (created by FormatToolbar)
in div (created by FormatToolbar)
in FormatToolbar (created by RichText)
in fill_FillComponent (created by Context.Consumer)
in Fill (created by BlockFormatControlsFill)
in BlockFormatControlsFill (created by Context.Consumer)
in IfBlockEditSelected(BlockFormatControlsFill) (created by RichText)
@gziolo Is this still the case, I think you worked on related things lately?
I was working on different issues lately. This is still valid and it's blocking #14845 - use SCRIPT_DEBUG in end-to-end test environment.
@talldan are you still working on it?
@gziolo Sorry, missed the ping. I think I lost track that I was supposed to be working on this. Sorry!
https://github.com/WordPress/gutenberg/issues/19642 looks like another one related to Slot, might be the same issue.
19642 looks like another one related to Slot, might be the same issue.
@diegohaz is working on a new implementation for SlotFill in https://github.com/WordPress/gutenberg/pull/19242, maybe it will fix this issue?
I'm still seeing those Can't perform a React state update warnings when applying the refactored SlotFill module to BlockControls. Other parts are still using the old implementation though (also because the new SlotFill implementation only supports the current <Slot bubblesVirtually /> scenario, which uses React Portal). I guess that, even if it fixes the warning, we would only get rid of it completely when all the other slots are updated.
By the way, #19242 (slot fill refactor) is kind of done and is blocking other tasks (#20008). I would appreciate any review there! 😆
BTW, the slot fill issue still exists:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in SlotComponent (created by Context.Consumer)
in Slot (created by Slot)
in Slot (created by FormatToolbar)
in div (created by ToolbarGroupContainer)
in ToolbarGroupContainer (created by ToolbarGroup)
in ToolbarGroup (created by FormatToolbar)
in div (created by FormatToolbar)
in FormatToolbar (created by FormatToolbarContainer)
in Fill (created by Fill)
in Fill (created by BlockFormatControlsFill)
in BlockFormatControlsFill (created by BlockFormatControlsFill)
in BlockFormatControlsFill (created by Context.Consumer)
in IfBlockEditSelected(BlockFormatControlsFill) (created by FormatToolbarContainer)
in FormatToolbarContainer (created by RichText)
I'm also seeing another state update on master:
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in ForwardRef(ToolbarContainer) (created by ForwardRef(Toolbar))
in ForwardRef(Toolbar) (created by NavigableToolbar)
in NavigableToolbar (created by BlockContextualToolbar)
in div (created by BlockContextualToolbar)
in BlockContextualToolbar (created by BlockPopover)
in div (created by Animate)
in div (created by ForwardRef)
in ForwardRef (created by Animate)
in Animate (created by Popover)
in PopoverDetectOutside (created by WithFocusOutside(PopoverDetectOutside))
in div (created by WithFocusOutside(PopoverDetectOutside))
in WithFocusOutside(PopoverDetectOutside) (created by Popover)
in Fill (created by Fill)
in Fill (created by Popover)
You can trigger it by going to post-new.php and clicking between the title and the main editor several times
I wonder if it happens here? It seems to fit the stack trace:
@noahtallen Does this happen before #20008?
No, I checked out the commit previous to that merge and it does not happen before that PR. I used the same post/post content to test as well. repro steps:
_before that PR, step 4 doesn't happen. no warning displays_
Thanks! :)
I'll take a look into that.
thanks for noticing!
Created a simple reproduction here: https://codesandbox.io/s/wordpress-slotfill-memory-leak-warning-nmcmc?file=/src/App.js
It doesn't seem to happen when Slot has bubblesVirtually prop.
It also doesn't happen when we memoize the Fill children (or if it's a primitive value like a string). So my current guess is that it's related to these lines: https://github.com/WordPress/gutenberg/blob/d15a208001f1d728d4f7ffb6b61239fc3fad5fbc/packages/components/src/slot-fill/fill.js#L35-L40
React elements (<div>test</div>) will be always different on every render.