-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Extract BlockThemePreviews-related code from the editor package #50863
Extract BlockThemePreviews-related code from the editor package #50863
Conversation
👋 Thanks for your first Pull Request and for helping build the future of Gutenberg and WordPress, @okmttdhr! In case you missed it, we'd love to have you join us in our Slack community, where we hold regularly weekly meetings open to anyone to coordinate with each other. If you want to learn more about WordPress development in general, check out the Core Handbook full of helpful information. |
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.
Thanks for the PR.
My initial question here is why are we using context? What's the benefit?
Could we not just pass props directly to the <EntitiesSavedStates>
component and control it's behaviour that way?
Maybe I missed something in prior conversations so please feel free to put me right if I've misunderstood.
Update: just noticed this in the description:
Another approach is to use props and just pass them. I'll write the pros/cons later.
I think it would be valuable to consider this tradeoff upfront before proceeding?
setIsDirtyContext( | ||
dirtyEntityRecords.length - unselectedEntities.length > 0 | ||
); |
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.
Instead of an effect here can we just set the initial value to be this? Generally setState within an effect is a clue that we should be doing this calculation on render.
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.
@getdave CC: @scruffian
Thank you for your comment!
I lifted states up and added how I did it in the PR description.
I'll add Testing Instructions/Screenshots and look into the failing tests tomorrow if the implementation makes sense.
That's probably my fault. I know in the past we've tried to avoid too much prop drilling so I suggested context as an alternative, but since we don't need to pass the props through multiple components it might be overkill in this case. |
@getdave After reading your comments, I'll go for using props this time! |
Do you have any examples of this currently? If not then I wouldn't over optimise for that. |
I've given this a good test and it seems to work as expected, great job. I think if we can just take care of the two points above we should be good to go :) |
Oh I also noticed that there are some test failures so we should also look at them. |
@getdave |
2004a51
to
415c7fb
Compare
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.
Thanks for continuing to work on this. I made some suggestions.
lib/experiments-page.php
Outdated
add_settings_field( | ||
'gutenberg-theme-previews', | ||
__( 'Block Theme Previews', 'gutenberg' ), | ||
'gutenberg_display_experiment_field', | ||
'gutenberg-experiments', | ||
'gutenberg_experiments_section', | ||
array( | ||
'label' => __( 'Enable Block Theme Previews', 'gutenberg' ), | ||
'id' => 'gutenberg-theme-previews', | ||
) | ||
); | ||
|
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 would be better to keep this PR surface area small and not remove the experiment in this PR.
Why? Because if we decide we need to roll back to making this an experiment we'll also have to revert all the other code changes. If there have been other changes to those files since then, the unfortunate developer will have to handle that which isn't something we should impose upon them.
Let's make the removal of the experiment a dedicated follow up PR.
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'm going to create another PR for 1f8961a 👍 (reverted it for this PR)
c.f. #50863 (comment)
|
||
const { EntitiesSavedStatesExtensible } = unlock( privateApis ); | ||
|
||
const EntitiesSavedStatesForPreview = ( { onClose } ) => { |
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.
This is nice. I would have just used an if statement for all this, but I really like the way you encapsulated this logic in a component.
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.
Thanks for all your work on this, you've done a great job. LGTM
Congratulations on your first merged pull request, @okmttdhr! We'd like to credit you for your contribution in the post announcing the next WordPress release, but we can't find a WordPress.org profile associated with your GitHub account. When you have a moment, visit the following URL and click "link your GitHub account" under "GitHub Username" to link your accounts: https://profiles.wordpress.org/me/profile/edit/ And if you don't have a WordPress.org account, you can create one on this page: https://login.wordpress.org/register Kudos! |
👋🏼 Hey @okmttdhr! If you have a moment, could you connect your GitHub account to your wordpress.org one? This change is slated to be included in the upcoming WordPress 6.3 release on August 8th, and it would be great if we could give you attribution by mentioning you on the credits screen. You can find more details on how contributions are tracked and how connecting GitHub accounts helps in this post on the Make WordPress Core blog. |
Hello, @jeffpaul 👋 I connected my GitHub account to wporg. Thanks for letting me know! |
What?
Why?
BlockThemePreviews is only enabled in the Site Editor. So, it should be in the edit-site package.
Please refer to #50177
How?
I implemented it so that
EntitiesSavedStates
can be extensible from the parent component and remove the BlockThemePreviews-related code there.Basically, I just used props to extend the component, but the tricky part is that we need to refer to
isDirty
in the parent component since we have logic like this;In this case, I decided to
3. Lift the states up
but what do you think?1.
useEffect
My first thought to achieve this is to use
useEffect
.The code is like the below,
useEffect
notifies the state changes to the parent;146e452#diff-c5815980e7aa19efd287aaa72512569ac7de514d74679af2f0b099f8a9369bc5R146-R153
This code was easy but had the problem of rendering components more than necessary.
c.f. https://react.dev/learn/you-might-not-need-an-effect#notifying-parent-components-about-state-changes
2. Update everything in a single pass
To reduce unnecessary rendering, we can update the states directly instead of
useEffect
.https://react.dev/learn/you-might-not-need-an-effect#notifying-parent-components-about-state-changes:~:text=Delete%20the%20Effect%20and%20instead%20update%20the%20state%20of%20both%20components%20within%20the%20same%20event%20handler%3A
In our case, we can update
unselectedEntities
anddirtyEntityRecords
at the following locations and notify to the parent;https://github.com/WordPress/gutenberg/blob/024d004/packages/editor/src/components/entities-saved-states/index.js#L57
https://github.com/WordPress/gutenberg/blob/024d004/packages/editor/src/components/entities-saved-states/index.js#L128
However, in this case,
isDirty
must be calculated on the parent side, which may be difficult to maintain if the logic becomes more complex in the future.3. Lift the states up
Another approach is to lift the states up.
https://react.dev/learn/you-might-not-need-an-effect#passing-data-to-the-parent
I created the custom hook to compute
isDirty
and the related values. Also, I implementedEntitiesSavedStatesExtensible
andEntitiesSavedStates
components for the parent that doesn't needisDirty
.54332d2
Testing Instructions
Testing Instructions for Keyboard
Activate & Save
it.Screenshots or screencast
Screen.Recording.2023-05-25.at.14.04.55.2.480.mov