crank icon indicating copy to clipboard operation
crank copied to clipboard

Use `key`, `ref` and `static` props instead of the variants

Open brainkim opened this issue 1 year ago • 5 comments

Related to #90

For the longest time, I wanted to use special sigils to distinguish virtual DOM properties like key and ref from normal DOM props. It started with a convention where special props were named crank-key and crank-ref. This was shortened to c-key and c-ref in a later version, and finally shortened even further to $key and $ref. My primary rationalization was that key and ref are neither properties nor attributes on the DOM, and I didn’t want to step on the names for custom elements.

I now consider this to be a lapse of judgment, and for that I am deeply sorry to all three of my Crank users. The reality is that these prop names are already likely poisoned due to the popularity of React, so that no one would likely ever define properties or attributes named key or ref anyways. Furthermore, this minor difference from React can cause a lot of confusion.

Going forward, the special props key, ref and static will all be unprefixed. This should land in the next minor version (0.6.0).

brainkim avatar Jun 12 '23 19:06 brainkim

I don't mind the existing behavior, especially with the $key and $ref variants (crank-key and crank-ref seem a bit lengthy). It adds clarity IMO that these props are different, and the visual distinction maybe helps hint at why they won't be accessible as properties within the component.

Out of curiosity, why can't the $key or $ref be passed through as a property to the component?

canadaduane avatar Oct 15 '23 15:10 canadaduane

@canadaduane The key and ref props have been removed from props, a tradition started by React. On the use-case side of actually being able to access key and ref in a component, I’m not sure. Honestly, I have often wanted to know the key of a component, usually for debugging purposes.

brainkim avatar Dec 27 '23 11:12 brainkim

Personally, I would use two sets like so (since we already have $-prefixed props):

  • keep $key, $ref: assign the key and ref, but do not pass as props
  • introduce key, ref: assign the key and ref, and also pass as props

This makes it less "magical" in the sense that if props are passed to the component, they are readable by the component. And if they have special $ syntax, maybe that breaks the rule.

My 2c :)

canadaduane avatar Dec 28 '23 01:12 canadaduane

Personally, I would use two sets like so (since we already have $-prefixed props):

  • keep $key, $ref: assign the key and ref, but do not pass as props
  • introduce key, ref: assign the key and ref, and also pass as props

Interesting compromise! I haven’t sincerely thought about the actual deep reasons for erasing special props from component props to be honest so I’m not sure about the advantage of this distinction in behavior.

Even in the use-case where we want to access a key and ref from within a component, my guess is that this could probably be done as a computed property on the context, as in console.log(this.key) rather than by passing it as props. On the other hand, if it’s available on the context, then why go through the trouble of not having it in props? I’m honestly wondering if we could just not bother erasing special props at all. It might even be a smidge more performant if we can pass an element’s props directly to the component... I’m looking at the code and think this could result in a nice memory optimization.

The main reason I want to use un-prefixed special props is that a lot more code is written by machines and they get it wrong. In an age of LLMs, it’s better to just be cross-compatible.

I still think that it’s kind of weird that we’re just not allowed to write components or HTML with the props/attributes key and ref, given that they’re really useful computing concepts. But I initially thought I wanted more special properties, and so far $static is the only one I could come up with, so now I’m thinking the prefix was a mistake. Also, the children prop has special qualities but is un-prefixed, so I’m not sure about this whole not wanting namespaces to clash.

I dunno! It all feels like small stuff, it’s tough to make a decision.

brainkim avatar Dec 29 '23 07:12 brainkim

It seems good to lean towards giving more power to the app developer unless there are good reasons not to. As you've mentioned, key seems like a clear winner here--I can't think of a downside, unless it were writable, and I don't think it would be. So that leaves ref... is it dangerous to have a ref hanging around and accessible from within the thing ref'ed? On the surface, it seems like kind of a cool power.

canadaduane avatar Dec 30 '23 06:12 canadaduane

Implemented in 0.6

brainkim avatar May 24 '24 14:05 brainkim