-
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
Move the editor settings into the editor's store #6500
Conversation
wideControlsEnabled: settings.alignWide, | ||
export default withSelect( | ||
( select ) => ( { | ||
wideControlsEnabled: select( 'core/editor' ).getEditorSettings().alignWide, |
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.
Targeted selectors like doesEditorSuppoortWideAlignment
could be added later.
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.
What about having an option to enabling this support to the existing selector?
wideControlsEnabled: select( 'core/editor' ).getEditorSettings( 'alignWide' ),
// or singular
wideControlsEnabled: select( 'core/editor' ).getEditorSetting( 'alignWide' ),
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.
Yes, why not 👍 I'll leave those to a separate PR because this one is already big enough :)
return { | ||
items: getFrecentInserterItems( allowedBlockTypes, 4 ), |
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.
Since it's in state now, we could improve this selector to avoid the allowedBlockTypes
argument.
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.
Nice 👍
* Internal dependencies | ||
*/ | ||
import { withEditorSettings } from '../editor-settings'; | ||
import { withSelect } from '@wordpress/data'; |
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.
Several components in the blocks module make use of these settings. These components should be moved to the editor
module (related #6275) before merging this PR to ensure select( 'core/editor' )
is available.
4c2af3d
to
4db91af
Compare
Nice! This will solve a few pain points I've seen (e.g. #6067 cc. @brandonpayton) Why use React/Redux to manage this data at all, though? Editor settings don't change throughout the lifetime of the application, so they could just as well be stored in a constant somewhere e.g. |
|
||
export default EditorSettings; | ||
|
||
export const withEditorSettings = ( mapSettingsToProps ) => createHigherOrderComponent( |
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.
Do we need to deprecate
this for a few versions? I note that it's public via @wordpress/blocks
.
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.
Good point, I'll wrangle something
Why shouldn't they change? I mean if we built our application to be reactive to change to editor settings, that's a win? And we do have a setting that can change: |
4db91af
to
42485b5
Compare
I am a big fan of this because it gives us a single place to reason about and work with editor state. |
f051ab5
to
03ec2c1
Compare
Fair point 🙂
We currently fake this by overriding the setting value in |
Not certain I agree, we do change the editorSettings which is a concept of the |
core-blocks/image/block.js
Outdated
} ), | ||
] )( ImageBlock ); | ||
return { | ||
settings: select( 'core/editor' ).getEditorSettings(), |
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.
Minor: This change assume settings can now be dynamic, so we will re-render each time settings change, we just use maxWidth from settings so maybe we can just pass maxWidth now instead of all the settings.
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.
Good point, though there's not real change compared to the previous version in term of rerendering. The previous version, the settings were also dynamic since it was using the new context API.
editor/store/reducer.js
Outdated
* blockTypes boolean|Array Allowed block types | ||
* hasFixedToolbar boolean Whether or not the editor toolbar is fixed | ||
*/ | ||
const DEFAULT_SETTINGS = { |
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.
Maybe we should export this constant in './defaults'. Given that we have already had a file for defaults.
SETUP_EDITOR( action ) { | ||
const { post, settings } = action; | ||
SETUP_EDITOR( action, { getState } ) { | ||
const { post } = action; |
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 think settings was part of the setup editor action just because of this effect. And now we are not using it anymore or passing it, so In my opinion, the settings parameter should be removed from setupEditor action.
} | ||
|
||
componentDidUpdate( prevProps ) { | ||
if ( this.props.settings !== prevProps.settings ) { |
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 really like this approach, the user changes a preference in the edit post store. That preference changes the props passed to the editor and the editor updates its configuration. I think this is the right way to communicate between stores 👍
I think we will probably have more uses of this pattern in the future.
The problem we may have is that when settings are updated a rerender happens, then componentDidUpdate is executed, we change the store and we may do another rerender after the store is changed. In this case, I think it is not problematic as we don't depend on the settings of the store, so we don't have double rerenders.
But, I would like to know what are your thoughts on this alternative approach as in other situations the prop may change frequently:
Add a withSelect that selects the current settings from the store, so we have currentSettings (old settings) and settings. Use getDerivedStateFromProps to compare both settings and if they are different call props.updateEditorSettings. In this case, we are updating the store before a re-render but it sounds like a hack. I'm not certain of what would be the correct solution for this pattern.
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.
The problem with getDerivedStateFromProps
is that it's a static function with no access to the previous props.
Yes, there's a potential double rendering when we use componentDidUpdate
but there's nothing noticeable for the end user because even if React calls the DOM update methods, the UI won't render until the next JavaScript event loop item which is not called until the double rerendering finishes (Learned this from Dan Abramov's tweets :P )
I really like the changes we have here as it moves us further in the direction of having all data available via withSelect. In my tests, this seems to be working well 👍 Awesome work! |
03ec2c1
to
bb5cfe2
Compare
Thanks all for your feedback, I think I've addressed all the feedback here, so moving forward soon. |
In this PR I'm trying to get rid of
withEditorSettings
and just use the editor's store to hold these settings. It doesn't make sense to use another context provider for these while the editor store behaves in the exact same way.