Replace onbeforeupdate
with m.retain()
#2919
Replies: 9 comments
-
Love it. Super intuitive. Since it's just a vnode, would it work in any part of a tree, not just components? |
Beta Was this translation helpful? Give feedback.
-
@gilbert Correct. It's intended to replace both the attribute the component method. |
Beta Was this translation helpful? Give feedback.
-
good old |
Beta Was this translation helpful? Give feedback.
-
Yup, and that's where the name came from. I miss it badly. |
Beta Was this translation helpful? Give feedback.
-
So, in light of some recent discussion in #2690, I'd like to propose an alternative: const Comp = {
view(vnode) {
return m.updateIf(vnode.attrs, (prev, next) => cond, () => tree)
}
} This would operate similar to Conveniently, this would allow easy diffing of not only attributes, but other state, too, and unlike React, it's very flexible. It's a little more magical than If you wanted a direct equivalent of const hasOwn = {}.hasOwnProperty
m.memo = C => ({
view: ({attrs}) => m.updateIf(
Object.entries(vnode.attrs),
(prev, next) => (
prev.length === next.length &&
prev.every(([k, v]) => hasOwn.call(vnode.attrs, k) && v === vnode.attrs[k])
),
() => C(m.censor(attrs))
)
}) |
Beta Was this translation helpful? Give feedback.
-
Okay, let me go back a little on that: that's not flexible enough for efficient DOM patching. It only really helps with the diffing (part of the allure of function Comp(ctx) {
return m.compare(ctx.attrs, (prev, next) => cond ? tree : m.retain())
} It's a few more characters, but it's not that much worse, and it also means that combined with #2689, we don't need to provide any "previous" functionality. Here's the above // `m.updateIf`
const hasOwn = {}.hasOwnProperty
m.memo = C => ({attrs}) => m.updateIf(
Object.entries(attrs),
(prev, next) => (
prev.length === next.length &&
prev.every(([k, v]) => hasOwn.call(attrs, k) && v === attrs[k])
),
() => C(attrs)
)
// `m.compare(value, init)` + `m.retain()`
const hasOwn = {}.hasOwnProperty
m.memo = C => ({attrs}) => m.compare(Object.entries(attrs), (prev, next) => (
prev == null ||
prev.length === next.length && prev.every(([k, v]) => hasOwn.call(attrs, k) && v === attrs[k])
? C(attrs)
: m.retain()
))
// Minified `m.updateIf` vs `m.compare`
const h={}.hasOwnProperty;m.memo=C=>({attrs:a})=>m.updateIf(Object.entries(a),(p,n)=>p.length===n.length&&p.every(([k,v])=>h.call(a,k)&&v===a[k]),()=>C(a))
const h={}.hasOwnProperty;m.memo=C=>({attrs:a})=>m.compare(Object.entries(a),(p,n)=>null==p||p.length===n.length&&p.every(([k,v])=>h.call(a,k)&&v===a[k])?C(a):m.retain()) I'm not tied to the name, but that's the idea. Conversely, we can just provide |
Beta Was this translation helpful? Give feedback.
-
I have an idea for an api but first I need to know: how does |
Beta Was this translation helpful? Give feedback.
-
@gilbert It'd require a node slot (like |
Beta Was this translation helpful? Give feedback.
-
Update: I'm reverting back to the original form as described in the issue for now. It's simpler, easier to wrap your head around, and more likely to get places. |
Beta Was this translation helpful? Give feedback.
-
Mithril version:
Platform and OS:
Project:
Is this something you're interested in implementing yourself? Very
Description
Replace this pattern:
With this:
m.retain()
would have atag
of"="
, and that's how we'd detect. This can be used anywhere a child is, and on first render would be equivalent toundefined
(you're essentially explicitly "retaining" no tree, so it's consistent).Why
It's simpler for us to implement and simpler for users to implement. It's also more flexible.
This is something we've wanted to do for a while.
Possible Implementation
createVnode
to do nothing onvnode.tag === "="
.updateVnode
to, onvnode.tag === "="
, transfer state much like whatshouldNotUpdate
does when preventing update, but also transfer tags and attributes, in effect modifying them.retain()
vnode to be the actual desired vnode. (This avoids having to replace nodes in the tree, which makes this a lot less complicated.)shouldNotUpdate
check inupdateNode
.updateComponent
to invokevnode.state.view(vnode, old)
.Open Questions
Beta Was this translation helpful? Give feedback.
All reactions