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

Move the editor settings into the editor's store #6500

Merged
merged 5 commits into from
May 10, 2018

Conversation

youknowriad
Copy link
Contributor

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.

wideControlsEnabled: settings.alignWide,
export default withSelect(
( select ) => ( {
wideControlsEnabled: select( 'core/editor' ).getEditorSettings().alignWide,
Copy link
Contributor Author

@youknowriad youknowriad Apr 30, 2018

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.

Copy link
Member

@gziolo gziolo Apr 30, 2018

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' ),

Copy link
Contributor Author

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 ),
Copy link
Contributor Author

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.

Copy link
Member

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';
Copy link
Contributor Author

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.

@noisysocks
Copy link
Member

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. wp.editor.settings = { ... }.


export default EditorSettings;

export const withEditorSettings = ( mapSettingsToProps ) => createHigherOrderComponent(
Copy link
Member

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.

Copy link
Contributor Author

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

@youknowriad
Copy link
Contributor Author

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. wp.editor.settings = { ... }.

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: hasFixedToolbar.

@youknowriad youknowriad force-pushed the try/editor-settings-in-store branch from 4db91af to 42485b5 Compare May 7, 2018 14:36
@youknowriad youknowriad mentioned this pull request May 7, 2018
4 tasks
@brandonpayton
Copy link
Member

I am a big fan of this because it gives us a single place to reason about and work with editor state.

@youknowriad youknowriad force-pushed the try/editor-settings-in-store branch from f051ab5 to 03ec2c1 Compare May 7, 2018 16:24
@noisysocks
Copy link
Member

Why shouldn't they change? I mean if we built our application to be reactive to change to editor settings, that's a win?

Fair point 🙂

And we do have a setting that can change: hasFixedToolbar.

We currently fake this by overriding the setting value in <Editor> with isFeatureActive( 'fixedToolbar' ). If we go ahead with this approach, perhaps it would be worth refactoring this so that the actual editor setting itself changes.

@youknowriad
Copy link
Contributor Author

We currently fake this by overriding the setting value in with isFeatureActive( 'fixedToolbar' ).

Not certain I agree, we do change the editorSettings which is a concept of the editor module. But we keep also keep track of the value as a preference in the edit-post for persistence.

} ),
] )( ImageBlock );
return {
settings: select( 'core/editor' ).getEditorSettings(),
Copy link
Member

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.

Copy link
Contributor Author

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.

* blockTypes boolean|Array Allowed block types
* hasFixedToolbar boolean Whether or not the editor toolbar is fixed
*/
const DEFAULT_SETTINGS = {
Copy link
Member

@jorgefilipecosta jorgefilipecosta May 8, 2018

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;
Copy link
Member

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 ) {
Copy link
Member

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.

Copy link
Contributor Author

@youknowriad youknowriad May 9, 2018

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 )

@jorgefilipecosta
Copy link
Member

jorgefilipecosta commented May 8, 2018

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!

@youknowriad youknowriad force-pushed the try/editor-settings-in-store branch from 03ec2c1 to bb5cfe2 Compare May 9, 2018 12:22
@youknowriad
Copy link
Contributor Author

Thanks all for your feedback, I think I've addressed all the feedback here, so moving forward soon.

@youknowriad youknowriad merged commit 63abd32 into master May 10, 2018
@youknowriad youknowriad deleted the try/editor-settings-in-store branch May 10, 2018 08:02
@danielbachhuber danielbachhuber added this to the 2.9 milestone May 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants