Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: consecutive updates may trigger a blocks reset #18219

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions packages/block-editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import { noop } from 'lodash';
import { last, noop } from 'lodash';

/**
* WordPress dependencies
Expand All @@ -20,6 +20,7 @@ class BlockEditorProvider extends Component {
this.props.updateSettings( this.props.settings );
this.props.resetBlocks( this.props.value );
this.attachChangeObserver( this.props.registry );
this.isSyncingOutcomingValue = [];
}

componentDidUpdate( prevProps ) {
Expand All @@ -39,20 +40,22 @@ class BlockEditorProvider extends Component {
this.attachChangeObserver( registry );
}

if ( this.isSyncingOutcomingValue !== null && this.isSyncingOutcomingValue === value ) {
if ( this.isSyncingOutcomingValue.includes( value ) ) {
// Skip block reset if the value matches expected outbound sync
// triggered by this component by a preceding change detection.
// Only skip if the value matches expectation, since a reset should
// still occur if the value is modified (not equal by reference),
// to allow that the consumer may apply modifications to reflect
// back on the editor.
this.isSyncingOutcomingValue = null;
if ( last( this.isSyncingOutcomingValue ) === value ) {
this.isSyncingOutcomingValue = [];
}
} else if ( value !== prevProps.value ) {
// Reset changing value in all other cases than the sync described
// above. Since this can be reached in an update following an out-
// bound sync, unset the outbound value to avoid considering it in
// subsequent renders.
this.isSyncingOutcomingValue = null;
this.isSyncingOutcomingValue = [];
this.isSyncingIncomingValue = value;
resetBlocks( value );
}
Expand Down Expand Up @@ -119,7 +122,7 @@ class BlockEditorProvider extends Component {
// When knowing the blocks value is changing, assign instance
// value to skip reset in subsequent `componentDidUpdate`.
if ( newBlocks !== blocks ) {
this.isSyncingOutcomingValue = newBlocks;
this.isSyncingOutcomingValue.push( newBlocks );
}

blocks = newBlocks;
Expand Down