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

SlotFill: remove explicit rerender from portal version #67471

Merged
merged 2 commits into from
Dec 2, 2024

Conversation

jsnajdr
Copy link
Member

@jsnajdr jsnajdr commented Dec 2, 2024

Simplifies the SlotFill implementation (the portal "bubbles virtually" version by removing explicit rerender API and its calls from Fill. After this patch the rerender happens automatically when the slot in the slots observableMap is changed with the slots.set( name, ... ) call.

How to test:
All unit tests and e2e tests should pass.

@jsnajdr jsnajdr added [Type] Code Quality Issues or PRs that relate to code quality [Package] Components /packages/components labels Dec 2, 2024
@jsnajdr jsnajdr self-assigned this Dec 2, 2024
@jsnajdr jsnajdr requested a review from ajitbohra as a code owner December 2, 2024 11:55
Copy link

github-actions bot commented Dec 2, 2024

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Co-authored-by: jsnajdr <[email protected]>
Co-authored-by: tyxla <[email protected]>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@@ -20,18 +19,15 @@ import type { FillComponentProps } from '../types';
export default function Fill( { name, children }: FillComponentProps ) {
const registry = useContext( SlotFillContext );
const slot = useObservableValue( registry.slots, name );
const [ , rerender ] = useReducer( () => [], [] );
const ref = useRef( { rerender } );
const instanceRef = useRef( {} );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rerender API goes away and the fill now registers only an unique instance object. I'm renaming it from ref to instance when registering, something that @tyxla asked for in one of the previous PRs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

};
const instance = instanceRef.current;
registry.registerFill( name, instance );
return () => registry.unregisterFill( name, instance );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This effect stays the same except renaming the ref variable to instanceRef etc.

ref: ref || slot?.ref,
fillProps: fillProps || slot?.fillProps || {},
} );
slots.set( name, { ref, fillProps } );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A drive-by change removing redundant code. All the registerSlot calls always include both the ref and fillProps values. Inheriting them from the previous slot value has no effect.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense 👍

// Force update fills.
slotFills.forEach( ( fill ) => fill.rerender() );
}
slots.set( name, { ref, fillProps } );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the key change in this PR! Instead of silently updating a field with slots.get( name ).fillProps = fillProps, we call slots.set. That sets a new value and triggers calling all observableMap listeners, leading to automatic rerendering of all fills.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much clearer and more concise, looks great 🚀

}, [ registerSlot, unregisterSlot, name ] );
registry.registerSlot( name, ref, fillPropsRef.current );
return () => registry.unregisterSlot( name, ref );
}, [ registry, name ] );
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A mere style change: don't destructure fields of registry. Simplifies the hook dependencies.

Copy link
Member

@tyxla tyxla left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, nice simplification and cleanup 🚀

@@ -20,18 +19,15 @@ import type { FillComponentProps } from '../types';
export default function Fill( { name, children }: FillComponentProps ) {
const registry = useContext( SlotFillContext );
const slot = useObservableValue( registry.slots, name );
const [ , rerender ] = useReducer( () => [], [] );
const ref = useRef( { rerender } );
const instanceRef = useRef( {} );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

ref: ref || slot?.ref,
fillProps: fillProps || slot?.fillProps || {},
} );
slots.set( name, { ref, fillProps } );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense 👍

// Force update fills.
slotFills.forEach( ( fill ) => fill.rerender() );
}
slots.set( name, { ref, fillProps } );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much clearer and more concise, looks great 🚀

Copy link

github-actions bot commented Dec 2, 2024

Flaky tests detected in efbd839.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/12121082461
📝 Reported issues:

@jsnajdr jsnajdr merged commit 6689c77 into trunk Dec 2, 2024
63 checks passed
@jsnajdr jsnajdr deleted the update/slotfill-remove-rerender branch December 2, 2024 16:02
@github-actions github-actions bot added this to the Gutenberg 19.9 milestone Dec 2, 2024
@Mamaduka
Copy link
Member

Mamaduka commented Dec 3, 2024

Thank you, @jsnajdr!

im3dabasia pushed a commit to im3dabasia/gutenberg that referenced this pull request Dec 4, 2024
* SlotFill: remove explicit rerender from portal version

* Add changelog entry

Co-authored-by: jsnajdr <[email protected]>
Co-authored-by: tyxla <[email protected]>
michalczaplinski pushed a commit that referenced this pull request Dec 5, 2024
* SlotFill: remove explicit rerender from portal version

* Add changelog entry

Co-authored-by: jsnajdr <[email protected]>
Co-authored-by: tyxla <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Components /packages/components [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants