-
Notifications
You must be signed in to change notification settings - Fork 79
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
Support for React-like ref
s?
#184
Comments
What's the fully requested functionality? |
[Edit: fixed the URLs for the demos several times]
I basically meant that:
For the latter please check the following React demo (everything is working fine there ... Preact and Dyo are working accordingly): By the way: This is also not working with the unmodified uhtml library: |
Sorry, I have mixed up some of the URLs in my previous comment - have fixed it. |
We don't really have to support the exact API as React, Preact, since Superfine does not seek compatibility with any of them, but if that's all it takes or even a little more, I'd definitely consider adding this to the project. Do you want to work on a PR? |
Sure, I can provide a PR if you like. This is working for my small demo, but I have to check some edge cases before I can prepare the PR for superfine. |
Don't worry too much about code style or golfing the code too much at this point. We'll get to that after it works. 💯 |
@jorgebucaran Could you please tell me, what shall be done with the unit test for this change? My initial version of the superfine tests (in one of my projects) is using Jest but I can switch to whatever test library you like: The tests are really important, I would have done an ugly mistake if I didn't implement the test suite for that |
I'm not switching test libraries.
Yeah, I don't have a Windows box, so I haven't been able to test Twist on it. I want to fix it, though. |
Do you mind ELI5 what |
Let's assume you have a fancy component library which is based on
If I understand that correctly it may have been possible in the old days of with function ref(refObjectOrCallback) {
return {
oncreate: ...,
onupdate: ...,
onremove: ...
}
} This may work the same way as React-like refs do. Nevertheless the |
Do you have an example using |
I agree this feature would be nice to have. I faced a similar issue just yesterday when trying to making an accessible drop down menu. I was trying to call If I understand correctly the proposed API is this? Where ref returns a function, that, when passed as a prop in your view, is called by superfine while patching, which returns the element. import { h, text, patch, ref } from 'superfine'
const Component = () => {
const parentRef = ref()
return h('div', { ref: parentRef }, [
h('div', {
onclick: () => {
parentRef.remove() // or something
}
}, [
text('remove parent')
]),
text('parent')
])
} |
@jorgebucaran Sorry, I completely forgot to answer. You mean something like @whaaaley's example? But why exactly is the animation important? Let me know and I will prepare a little demo. @whaaaley It should be [Edit] @whaaaley Actually a ref can be both a function or an object type Ref<T> = { current: T | null } | ((ref: T | null) => void) |
The animation is important because it's one of the common use cases for lifecycle events, which this feature resembles. |
@mcjazzyfunky That's interesting. Is there an advantage to using the object? Maybe it avoids the import? I feel like using a Also I remember animations with lifecycle events was a hot issue for while in Hyperapp. This seems like a decent solution to me. I do like it more than the old lifecycle events at least. |
@whaaaley Actually in some cases a ref function suits better in other cases a ref object. Normally I use ref objects. Actually it's just one line of code to support both 😉 import { h, text, patch, ref } from 'superfine'
const Component = () => {
let divElem = null
return h('div', { ref: (elem) => { divElem = elem } }, [
h('div', {
onclick: () => {
divElem.remove() // or something
}
}, [
text('remove parent')
]),
text('parent')
])
} |
@mcjazzyfunky I see now. That's very similar to the old lifecycle events. (That's not to say I wouldn't benefit from them coming back in a limited capacity. It's always super awkward to call methods on elements.) |
Animating the removal of a DOM element is challenging because Superfine has to defer removing the element after the animation and there's currently no way to do that without mutation observers or hiding the element instead of removing it (which is not too bad). |
Sorry if I'm missing something obvious (I usually am), but what about Edit: I think the main appeal of refs is just to avoid putting queries all over the place rather than try to hook into lifecycles. Doing a query feels incorrect when the node refs are right under our feet. Here's a demo I pulled out of one of my apps, a markdown text editor with synced scrollbars. Without refs a query would have to be run on every scroll event. https://codepen.io/dustindowell/pen/zYNePEp |
@jorgebucaran Not really sure whether this is want you've meant, but please see here: Please let me know when you need something more/else. [Edit]: Actually this demo does not use refs ... where exactly do I need refs for animations? |
What's the difference between refs and the old oncreate, onupdate, and onremove lifecycle events? |
A different, but out-of-the-box better useable API for basically the same thing. Refs may be a tiny little less powerful, as they do not care about
And refs support both ref callback functions and ref objects. What have been the use cases for |
I JUST realized that we don't really need this feature because it already exists! Well maybe... If there's any caveats to doing it this way please let me know, but so far so good in my current apps. import { h, text, patch } from 'superfine'
const view = () => {
const ref = { vnode: null }
const click = () => {
console.log(ref.vnode.node)
}
return ref.vnode = h('div', { onclick: click }, [
text('hello')
])
}
const node = document.getElementById('app')
patch(node, view) Edit: This combined with a little once lock utility simulates export default () => {
const storage = []
let lock = false
const handler = () => {
lock = true
for (let i = 0; i < storage.length; i++) {
storage[i]()
}
}
return fn => {
storage.push(fn)
if (!lock) {
window.requestAnimationFrame(handler)
}
}
} |
Wouldn't it be a nice and useful feature if
superfine
supportedref
pseudo properties like React, Preact, Dyo, uhtml etc. do?Here's a little demo (based on a R&D web-component toy library that uses a
ref
-supporting patched version ofsuperfine
internally):TypeScript version
JavaScript version
FYI: Here's a naive quick'n'dirty implementation which obviously only provides part of the requested functionality: LINK
The text was updated successfully, but these errors were encountered: