-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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 RichText rerendering when it shouldn't #12161
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,8 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import memize from 'memize'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
|
@@ -115,6 +120,40 @@ function updateAnnotationsWithPositions( annotations, positions, { removeAnnotat | |
} ); | ||
} | ||
|
||
/** | ||
* Create prepareEditableTree memoized based on the annotation props. | ||
* | ||
* @param {Object} The props with annotations in them. | ||
* | ||
* @return {Function} The prepareEditableTree. | ||
*/ | ||
const createPrepareEditableTree = memize( ( props ) => { | ||
const { annotations } = props; | ||
|
||
return ( formats, text ) => { | ||
if ( annotations.length === 0 ) { | ||
return formats; | ||
} | ||
|
||
let record = { formats, text }; | ||
record = applyAnnotations( record, annotations ); | ||
return record.formats; | ||
}; | ||
} ); | ||
|
||
/** | ||
* Returns the annotations as a props object. Memoized to prevent re-renders. | ||
* | ||
* @param {Array} The annotations to put in the object. | ||
* | ||
* @return {Object} The annotations props object. | ||
*/ | ||
const getAnnotationObject = memize( ( annotations ) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of memoizing function, I think it would be better for the That said, we're kind of running out of time, so I'm not considering this as blocking at the moment as it's a forward-compatible change. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, this sounds better. |
||
return { | ||
annotations, | ||
}; | ||
} ); | ||
|
||
export const annotation = { | ||
name: FORMAT_NAME, | ||
title: __( 'Annotation' ), | ||
|
@@ -128,21 +167,9 @@ export const annotation = { | |
return null; | ||
}, | ||
__experimentalGetPropsForEditableTreePreparation( select, { richTextIdentifier, blockClientId } ) { | ||
return { | ||
annotations: select( STORE_KEY ).__experimentalGetAnnotationsForRichText( blockClientId, richTextIdentifier ), | ||
}; | ||
}, | ||
__experimentalCreatePrepareEditableTree( { annotations } ) { | ||
return ( formats, text ) => { | ||
if ( annotations.length === 0 ) { | ||
return formats; | ||
} | ||
|
||
let record = { formats, text }; | ||
record = applyAnnotations( record, annotations ); | ||
return record.formats; | ||
}; | ||
return getAnnotationObject( select( STORE_KEY ).__experimentalGetAnnotationsForRichText( blockClientId, richTextIdentifier ) ); | ||
}, | ||
__experimentalCreatePrepareEditableTree: createPrepareEditableTree, | ||
__experimentalGetPropsForEditableTreeChangeHandler( dispatch ) { | ||
return { | ||
removeAnnotation: dispatch( STORE_KEY ).__experimentalRemoveAnnotation, | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -4,6 +4,8 @@ | |||||||||||||||||||||
import createSelector from 'rememo'; | ||||||||||||||||||||||
import { get, flatMap } from 'lodash'; | ||||||||||||||||||||||
|
||||||||||||||||||||||
const emptyArray = []; | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor: I think in other places we called this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't be bad to have the same comment: gutenberg/packages/editor/src/store/selectors.js Lines 57 to 66 in 563ef41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Related guideline: https://github.com/WordPress/gutenberg/blob/master/docs/contributors/coding-guidelines.md#constants |
||||||||||||||||||||||
|
||||||||||||||||||||||
/** | ||||||||||||||||||||||
* Returns the annotations for a specific client ID. | ||||||||||||||||||||||
* | ||||||||||||||||||||||
|
@@ -19,7 +21,7 @@ export const __experimentalGetAnnotationsForBlock = createSelector( | |||||||||||||||||||||
} ); | ||||||||||||||||||||||
}, | ||||||||||||||||||||||
( state, blockClientId ) => [ | ||||||||||||||||||||||
get( state, blockClientId, [] ), | ||||||||||||||||||||||
get( state, blockClientId, emptyArray ), | ||||||||||||||||||||||
] | ||||||||||||||||||||||
); | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
@@ -54,7 +56,7 @@ export const __experimentalGetAnnotationsForRichText = createSelector( | |||||||||||||||||||||
} ); | ||||||||||||||||||||||
}, | ||||||||||||||||||||||
( state, blockClientId ) => [ | ||||||||||||||||||||||
get( state, blockClientId, [] ), | ||||||||||||||||||||||
get( state, blockClientId, emptyArray ), | ||||||||||||||||||||||
] | ||||||||||||||||||||||
); | ||||||||||||||||||||||
|
||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
* External dependencies | ||
*/ | ||
import { mapKeys } from 'lodash'; | ||
import memize from 'memize'; | ||
|
||
/** | ||
* WordPress dependencies | ||
|
@@ -119,6 +120,14 @@ export function registerFormatType( name, settings ) { | |
|
||
dispatch( 'core/rich-text' ).addFormatTypes( settings ); | ||
|
||
const emptyArray = []; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
const getFunctionStackMemoized = memize( ( previousStack = emptyArray, newFunction ) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it work to keep the cache size to one? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, why do both this and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably not as we need one per RichText I think. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so, because a different function could be returned based on There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just wondering because it's probably best to keep cache size as small as possible. I'm guessing the issue is just consecutive calls and nothing else. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So how big is this cache going to grow? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No way to cache per instance? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a good question though |
||
return [ | ||
...previousStack, | ||
newFunction, | ||
]; | ||
} ); | ||
|
||
if ( | ||
settings.__experimentalGetPropsForEditableTreePreparation | ||
) { | ||
|
@@ -133,13 +142,13 @@ export function registerFormatType( name, settings ) { | |
const additionalProps = {}; | ||
|
||
if ( settings.__experimentalCreatePrepareEditableTree ) { | ||
additionalProps.prepareEditableTree = [ | ||
...( props.prepareEditableTree || [] ), | ||
additionalProps.prepareEditableTree = getFunctionStackMemoized( | ||
props.prepareEditableTree, | ||
settings.__experimentalCreatePrepareEditableTree( props[ `format_${ name }` ], { | ||
richTextIdentifier: props.identifier, | ||
blockClientId: props.clientId, | ||
} ), | ||
]; | ||
} ) | ||
); | ||
} | ||
|
||
if ( settings.__experimentalCreateOnChangeEditableValue ) { | ||
|
@@ -155,16 +164,16 @@ export function registerFormatType( name, settings ) { | |
return accumulator; | ||
}, {} ); | ||
|
||
additionalProps.onChangeEditableValue = [ | ||
...( props.onChangeEditableValue || [] ), | ||
additionalProps.onChangeEditableValue = getFunctionStackMemoized( | ||
props.onChangeEditableValue, | ||
settings.__experimentalCreateOnChangeEditableValue( { | ||
...props[ `format_${ name }` ], | ||
...dispatchProps, | ||
}, { | ||
richTextIdentifier: props.identifier, | ||
blockClientId: props.clientId, | ||
} ), | ||
]; | ||
} ) | ||
); | ||
} | ||
|
||
return <OriginalComponent | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this added as a dependency.