The data-wp-client-only-component
directive
#67306
luisherranz
started this conversation in
Interactivity API
Replies: 1 comment 6 replies
-
Works great, @luisherranz! 🙂 Not a big deal, but I noticed the warning:
being fired when using the I tried the following to suppress the warning, but alas it does not work as I expected. I think It might be because we don't re-export the import { directive } from './private-apis';
// We'd have to re-export Preact's options in the `@wordpress/interactivity` package.
import { options } from 'preact';
// data-wp-client-only-component
directive(
'client-only-component',
({ directives: { ['client-only-component']: comp }, element, evaluate }) => {
options._hydrationMismatch = () => {};
const entry = comp.find(({ suffix }) => suffix === null);
return evaluate(entry)(element.props);
}
); |
Beta Was this translation helpful? Give feedback.
6 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Let's start working on a directive that allows loading Preact components directly into the Interactivity API 🙂
First, for anyone reading this, it's very important to understand that these Preact components cannot be rendered in PHP and, therefore:
Therefore, these components should only be used for HTML that doesn't need to be filtered and that isn't displayed in the initial rendering of the page.
Let's hope that the developers understand, simply from the directive's name, that these components only work on the client. However, the documentation should also be very explicit.
That said, there are legitimate use cases for wanting to include this type of components in the frontend. So, let’s explore how it might work.
The directive itself is very simple at the code level, as internally, the Interactivity API is using Preact, so it’s enough to pass the component to the Interactivity API internals.
Initially, my idea is that it works as follows:
The element that contains
data-wp-client-only-component
will be replaced in the DOM with the Preact component.There's also the possibility that the Preact component can be added as a child, but it seems less flexible and intuitive to me.
The attributes of the element with the directive are passed as props to the component.
The Preact components can access the hooks by importing them directly from
@wordpress/interactivity
.There's also the possibility of importing them directly from
preact
by adding another entry to the import map, Since the hooks are slightly modified to work perfectly withindata-wp-run
. This is something we need to study carefully.The Preact components can access the stores of the Interactivity API: they can read and modify the global state and the local context, and execute actions.
They can simply do this by using
store('myPlugin')
, orgetContext('myPlugin')
. Everything should be reactive: when mutatingstate
, orgetContext
, the components accessing those properties will re-render.The HTML rendered on the server as a child of the element containing the directive
data-wp-client-only-component
, will be passed to the component, using thechildren
prop. This means that Preact components and rendered HTML can be interleaved on the server. This HTML can also include directives.I've created a prototype using StackBlitz that demonstrates how this type of component would work, and I've tried to cover all the cases explained here.
Although the directive is more or less clear, there are still a couple of things left to do:
evaluate
function auto-executes the functions passed by reference. It should be modified to allow passing a flag so that it doesn’t do this for this specific case.wp-scripts
with the--experimental-modules
argument, so that it utilizes the JSX of Preact in the frontend modules.Please, give it a try and share your feedback here.
Beta Was this translation helpful? Give feedback.
All reactions