Skip to content

Instantly share code, notes, and snippets.

@daronspence
Created May 20, 2020 20:30
Show Gist options
  • Save daronspence/c6ec117100a2e02c3beb24398415a008 to your computer and use it in GitHub Desktop.
Save daronspence/c6ec117100a2e02c3beb24398415a008 to your computer and use it in GitHub Desktop.
Contentful debug example
/**
* Essentially, the `onValueChanged` callback used to provide an object/array that was `===` during comparisons.
* In the last few days though, something changed and === was not working anymore.
* My solution is to serialize the values and compare those strings to ensure things are
not triggering unnecessary re-renders.
The external change handler is triggered even when the current editor updates the field value,
so we need to check it's equality to what is already in state,
otherwise the current editor will be in an endless loop of updating their own UI.
Flow:
- user types in field
- state changes
- app calls `sdk.field.setValue` when state changes
- onValueChanged triggered
- app evaluates if the onValueChanged callback incoming value is equal to what is in state
- update state if value has changed
- potential loop hell
Extension type is an array of Symbols
*/
// shortened for brevity
componentDidMount(){
this.detachExternalChangeHandler = this.props.sdk?.field?.onValueChanged(this.onExternalChange);
}
/**
* Set new state when list is updated from another Contentful editor.
* @param []|undefined value The updated field value.
*/
onExternalChange = (value) => {
// this used to work with `this.state.value === value`
if (JSON.stringify(this.state.value) === JSON.stringify(value)) {
return;
}
// If someone deletes all of the items in the widget, Contentful returns undefined.
// Convert that to an empty array to not break state.
if (typeof value === 'undefined') {
value = [];
}
this.setState({ value });
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment