Directives to execute a callback in the scope of the component #51863
Replies: 5 comments 4 replies
-
I've been trying to make a reusable store({
effects: {
isInView: ({ context, ref }) => {
const observer = new IntersectionObserver(([entry]) => {
context.status = entry.isIntersecting ? "Inside" : "Outside";
});
observer.observe(ref);
return () => observer.unobserve(ref);
},
},
}); into a composable function that others can use, like this: store({
effects: {
isInView: ({ context, ref }) => {
context.status = isInView(ref) ? "Inside" : "Outside";
},
},
}); The problem is that the callback that you pass to So if you try to put something like this inside a const useInView = (ref) => {
const [isInView, setIsInView] = useState(false);
useMemo(() => {
const observer = new IntersectionObserver(([entry]) => {
setIsInView(entry.isIntersecting);
});
observer.observe(ref);
}, []);
return isInView;
};
const Comp = () => {
const ref = useRef();
useEffect(() => {
const inView = useInView(ref.current); // Error!
});
// ...
}; Also, the destroy callback ( const useInView = (ref) => {
const [isInView, setIsInView] = useState(false);
const observer = useRef(null);
useMemo(() => {
observer.current = new IntersectionObserver(([entry]) => {
setIsInView(entry.isIntersecting);
});
observer.current.observe(ref);
}, []);
return [isInView, () => observer.current.unobserve(ref)];
}; Like this in Preact: const Comp = () => {
const ref = useRef();
useEffect(() => {
const [inView, clean] = useInView(ref.current); // Error!
// Use inView...
return clean;
});
// ...
}; And like this in the Interactivity API: store({
effects: {
isInView: ({ context, ref }) => {
const [isInView, clean] = isInView(ref);
context.status = isInView ? "Inside" : "Outside";
return clean; // Explicit.
},
},
}); There may be workarounds to the fact that hooks cannot be used inside On the other hand, the directives we have right now are just syntax sugar for
So I've started wondering if instead of adding yet another effect function, which may introduce confusion about when to use what, we should delegate effects to Preact and just have a single Any thoughts? If you want to play with this:
|
Beta Was this translation helpful? Give feedback.
-
If we don't replace |
Beta Was this translation helpful? Give feedback.
-
After a lot of thinking, this is my proposal for this discussion.
I'm not sure if it will be needed at some point or not, but in the future we could create a So we end up with these "hook" directives:
For the store, it's not going to be enforced but we need a standard property name to store that logic. We could keep the word We could use separate words, although the plurals of store("myPlugin", {
state: {
// ...
},
actions: {
// ...
},
inits: {
// ...
},
watches: {
// ...
},
runs: {
// ...
},
}); Or we could coin a new name that attempts to unite the three types. My two preferred alternatives are
store("myPlugin", {
state: {
// ...
},
actions: {
// ...
},
callbacks: {
// ...
},
});
store("myPlugin", {
state: {
// ...
},
actions: {
// ...
},
hooks: {
// ...
},
}); |
Beta Was this translation helpful? Give feedback.
-
First of all, thanks a lot for the information and the research here 🙂 And sorry for not answering in the previous comments, it was in my to-do list for a long time. I like the idea of having Regarding the store properties, I agree that |
Beta Was this translation helpful? Give feedback.
-
This was finally added as Closing this as completed 🙂 |
Beta Was this translation helpful? Give feedback.
-
Right now we have two directives to use
useEffect
:wp-effect
andwp-init
.wp-effect
is reactive and runs each timestate
orcontext
change, which is very handy. This is its code (simplified):And
wp-init
is not reactive and only runs when the element is created. This is its code (simplified):But sometimes you may want to execute code in the scope of the component outside of any
useEffect
, because you want to use your ownuseEffect
. For example:So, maybe we need a third directive for this, or modify the other two to accommodate for this possibility.
Suggestions are welcomed 🙂
Beta Was this translation helpful? Give feedback.
All reactions