-
Notifications
You must be signed in to change notification settings - Fork 11
Add priorities to directives #235
Add priorities to directives #235
Conversation
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.
Approving from my side because I tested and it seems to work great 🙂 (actually, it can help fixing this issue).
I just tested that it works. Please wait for a proper code review before merging it.
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.
Looks good to me as well. Great work, David 🙂
src/runtime/hooks.js
Outdated
// This element needs to be a fresh copy so we are not modifying an already | ||
// rendered element. This prevents an error with changes in | ||
// `element.props.children` not being reflected in `element.__k`. | ||
element = cloneElement(element); |
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.
@DAreRodz, can you explain this in more detail? Why is element
already rendered?
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 thing is that element
comes from the Directive
component, which never re-renders, so element
is always the same instance. If we don't clone it, it's unsafe to modify its properties the way we do inside directives because some element's internals wouldn't be updated (like the __k
property).
Co-authored-by: Luis Herranz <luisherranz@gmail.com>
Thanks for the reviews. PR is merged now. 🙌 As a follow-up, we can try improving the code with these changes:
|
What
This PR extends the
directive()
function API to add a new option calledpriority
, making directives on the same element to be evaluated in priority order. In such an element, directives with the same priority are evaluated together, wrapped in the same component, and those with less priority are wrapped in a nested component.Priorities follow the same schema as in WordPress, i.e., priority is a numeric value, lower numbers correspond with earlier execution ("more" priority), and the default value is
10
.Note that this value is per directive type, as it is set during directive definition. It doesn't allow changing the order in which directives are evaluated on different parts of the HTML.
A trivial example:
In addition, the priority for the
data-wp-context
directive has been set to5
.Why
Priorities allow directives to manipulate the element in which they appear, in the correct order. It is especially convenient for directives that add wrappers, like a context
Provider
(e.g.data-wp-context
), allowing other directives with less priority in the same element to consume that context.How
The main changes are in
/src/runtime/hooks.js
:usePriorityLevels
, that receives the object with all directives defined in an element and returns them sorted and grouped by priority.RecursivePriorityLevel
inside theDirective
component. It renders a component instance for each priority level thatusePriorityLevels
yields.