You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The opening comment of that issue proposes custom {attr}="value" syntax using curly braces; I believe we should stick with the same ComputedPropertyName used by ES2015 and not invent our own. Though this is up to discussion if the maintainers of the spec think that custom syntax fits in better with JSX.
Over half the comments in that issue are now about things unrelated to the proposal, so it's not a productive place to discuss since people new to the discussion have to wade through pages of unrelated comments first.
I wanted to include a spec, use cases, and information up front instead of deep in the comments.
Spec
The following update to JSXAttribute in the draft spec should be sufficient to my knowledge. New portion underlined.
JSXAttribute :
JSXAttributeName JSXAttributeInitializeropt
ComputedPropertyName JSXAttributeInitializer
This is not part of the spec, but for reference here is the ComputedPropertyName definition from ECMA-262.
ComputedPropertyName[Yield] :
[AssignmentExpression[In, ?Yield]]
Details
Here are some example JSX -> JS mappings. I've mixed existing syntax mappings with new ones to show how the new syntax relates to the old syntax.
<Foo[bar]/>;<Foo[ns]:name='foo'/>;<Foons:[name]='foo'/>;<Foo[ns]:[name]='foo'/>;<Foo[ns:name]='foo'/>;// This is not invalid from the JSX portion of the spec,// it's invalid because `ns:name` is an invalid AssignmentExpression.
Like we have a special key-only form of JSXAttribute, ES6 has a special {name}-only form of PropertyDefinition. But {[expr]} is not a valid ObjectLiteral in ES6.
Given that fact and it's unclear what [bar] would mean to JSX we should not include a mapping for the JSXAttributeInitializer-less form of JSXAttribute with a computed property.
It also doesn't make sense to allow mixing of computed properties and namespaced attribute names. Especially since computed property syntax with strings already allows you to include the : within the computed property.
These are taken care of in the spec by defining the syntax as another form of JSXAttribute without the opt and without using JSXAttributeName. Like how ES-262 has separate PropertyDefinition forms for PropertyName: AssignmentExpression and IdentifierReference.
Motivation
Computed property names are part of the ES2015 syntax for object literals. They are no less useful in JSX. Some ideas of what you could do with computed properties in JSX.
Vary the prop name on some condition.
// type examples: 'text' and 'checkbox'<inputtype={type}name={fieldName}[type==='checkbox' ? 'checked' : 'value']={formValues[fieldName]}/>// https://github.com/facebook/react-native/issues/7135consttestId=Platform.OS==='android'&&process.env.NOD_ENV==='test'
? 'accessibleLabel'
: 'testId';<View[testId]='my_id'/>
Pass symbols as prop names, allowing you to make internal/private props for a component or have a prop passed through 3rd party components without worrying about name collisions.
// https://facebook.github.io/react-native/docs/direct-manipulation.html#setnativeprops-to-clear-textinput-value// But with a field component in between hiding the TextInput,// but exposing it with props[nativeRef] for the few cases you need a workaroundconstnativeRef=Symbol('nativeRef');constMyInput=(props)=>(<Viewstyle={fieldStyles}><Labeltext={props.label}<TextInputref={props[nativeRef]}value={props.value}/></View>);constinputRef=React.createRef();<MyInput[nativeRef]={inputRef}/>inputRef.value..setNativeProps({text: ''});
An alternative to attrs: {} and events: {} allowing libraries like skatejs/val to differentiate between attributes and props. By using a function that returns a Symbol the library has registered a Symbol -> attribute mapping for. Or just returning it as a string prop name with some long prefix like const attr = (name) => '__SKATEJS_VAL_ATTRIBUTE__$' + name;.
// h.jsimport{createElement}from'react';importval,{attr,event}from'@skatejs/val';exportdefaultval(createElement);export{attr,event};// app.js/* @jsx h */importh,{attr,event}from'h';<WebComponentsomeProperty='bar'[attr('some-attribute')]='foo'[event('some-event')]={handleEvent}/>
IMO <Foo [bar] /> should function the same as <Foo [bar]={true} /> — this isn’t destructuring, and there really isn’t a reason as far as I can see to disallow this.
IMO <Foo [bar] /> should function the same as <Foo [bar]={true} /> — this isn’t destructuring, and there really isn’t a reason as far as I can see to disallow this.
It has no analog, [bar]= is pretty clearly the JSX version of [bar]: in ES2015. But [bar] looks more like array syntax randomly placed in an element.
However if the spec owners decide, or the consensus becomes, that we should allow this syntax I can update the proposal.
I'd like to propose we support JSX attributes with ES2015's computed property names
I am opening a separate issue from "AssignmentExpression in JSXAttributeName#21" because:
{attr}="value"
syntax using curly braces; I believe we should stick with the same ComputedPropertyName used by ES2015 and not invent our own. Though this is up to discussion if the maintainers of the spec think that custom syntax fits in better with JSX.Spec
The following update to
JSXAttribute
in the draft spec should be sufficient to my knowledge. New portion underlined.This is not part of the spec, but for reference here is the
ComputedPropertyName
definition from ECMA-262.Details
Here are some example JSX -> JS mappings. I've mixed existing syntax mappings with new ones to show how the new syntax relates to the old syntax.
The following syntax is not valid:
Like we have a special
key
-only form of JSXAttribute, ES6 has a special{name}
-only form of PropertyDefinition. But{[expr]}
is not a valid ObjectLiteral in ES6.Given that fact and it's unclear what
[bar]
would mean to JSX we should not include a mapping for the JSXAttributeInitializer-less form of JSXAttribute with a computed property.It also doesn't make sense to allow mixing of computed properties and namespaced attribute names. Especially since computed property syntax with strings already allows you to include the
:
within the computed property.These are taken care of in the spec by defining the syntax as another form of
JSXAttribute
without theopt
and without usingJSXAttributeName
. Like how ES-262 has separatePropertyDefinition
forms forPropertyName: AssignmentExpression
andIdentifierReference
.Motivation
Computed property names are part of the ES2015 syntax for object literals. They are no less useful in JSX. Some ideas of what you could do with computed properties in JSX.
Vary the prop name on some condition.
Pass symbols as prop names, allowing you to make internal/private props for a component or have a prop passed through 3rd party components without worrying about name collisions.
An alternative to
attrs: {}
andevents: {}
allowing libraries like skatejs/val to differentiate between attributes and props. By using a function that returns a Symbol the library has registered a Symbol -> attribute mapping for. Or just returning it as a string prop name with some long prefix likeconst attr = (name) => '__SKATEJS_VAL_ATTRIBUTE__$' + name;
.More possibilities if the "Registered prop as ref / [refProp]={value} and [customEvent]={handler}" RFC is accepted.
The text was updated successfully, but these errors were encountered: