Forked from sebmarkbage/JSXSpreadAttributes.md
Last active
September 14, 2015 19:15
-
-
Save qmmr/99111b6907113502ecb6 to your computer and use it in GitHub Desktop.
Revisions
-
sebmarkbage revised this gist
Oct 15, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -63,7 +63,7 @@ What's with the weird `...` notation? The `...` operator (or spread operator) is already supported for [arrays in ES6](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). We're also pushing to get the spread operator for object properties in ES7. You can read the full proposal here: [Object Rest and Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread) In fact, thanks to our JS transform pipeline, you can already use this in our code base as an experimental syntax: -
sebmarkbage revised this gist
Jul 8, 2014 . 1 changed file with 8 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,11 +1,14 @@ JSX Spread Attributes ===================== If you know all the properties that you want to place on a component a head of time, it is easy to use JSX: ```javascript var component = <Component foo={x} bar={y} />; ``` Mutating Props is Bad, mkay --------------------------- If you don't know which properties you want to set, you might be tempted to add them onto the object later: @@ -20,7 +23,7 @@ This is an anti-pattern because it means that we can't help you check the right The props should be considered immutable at this point. Mutating the props object somewhere else could cause unexpected consequences so ideally it would be a frozen object at this point. Constructing Your Props Before the Component -------------------------------------------- The lesson learned is that you should be constructing all your props first and then passing them into the component. @@ -34,7 +37,7 @@ In the early days of JSX you didn't have a way to pass a props object to your co ``` Spread Attributes ----------------- Now you can use a new feature of JSX called spread attributes: @@ -56,7 +59,7 @@ You can use this multiple times or combine it with other attributes. The specifi ``` What's with the weird `...` notation? ------------------------------------- The `...` operator (or spread operator) is already supported for [arrays in ES6](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). We're also pushing to get the spread operator for object properties in ES7. You can read the full proposal here: @@ -78,7 +81,7 @@ Merging two objects can be expressed as: ``` Rationale: Spread Syntax in JSX ------------------------------- _Why not `<div props={props} />`?_ -
sebmarkbage created this gist
Jul 8, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,107 @@ If you know all the properties that you want to place on a component a head of time, it is easy to use JSX: ```javascript var component = <Component foo={x} bar={y} />; ``` Mutating Props is Bad, mkay ------------------------------------ If you don't know which properties you want to set, you might be tempted to add them onto the object later: ```javascript var component = <Component />; component.props.foo = x; // bad component.props.bar = y; ``` This is an anti-pattern because it means that we can't help you check the right propTypes until way later. This means that your propTypes errors end up with a cryptic stack trace. The props should be considered immutable at this point. Mutating the props object somewhere else could cause unexpected consequences so ideally it would be a frozen object at this point. Constructing Your Props Before the Component ------------------------------------------------------------- The lesson learned is that you should be constructing all your props first and then passing them into the component. In the early days of JSX you didn't have a way to pass a props object to your component, so you had to resort to a plain function call: ```javascript var props = {}; props.foo = x; props.bar = y; var component = Component(props); // Where did my JSX go? ``` Spread Attributes ---------------------- Now you can use a new feature of JSX called spread attributes: ```javascript var props = {}; props.foo = x; props.bar = y; var component = <Component {...props} />; ``` The properties of the object that you pass in are copied onto the component's props. You can use this multiple times or combine it with other attributes. The specification order is important. Later attributes override previous ones. ```javascript var props = { foo: 'default' }; var component = <Component {...props} foo={'override'} />; console.log(component.props.foo); // 'override' ``` What's with the weird `...` notation? -------------------------------------------- The `...` operator (or spread operator) is already supported for [arrays in ES6](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). We're also pushing to get the spread operator for object properties in ES7. You can read the full proposal here: [Object Rest Destructuring and Spread Initializer](https://gist.github.com/sebmarkbage/aa849c7973cb4452c547) In fact, thanks to our JS transform pipeline, you can already use this in our code base as an experimental syntax: ```javascript var oldObj = { foo: 'hello', bar: 'world' }; var newObj = { ...oldObj, foo: 'hi' }; console.log(newObj.foo); // 'hi'; console.log(newObj.bar); // 'world'; ``` Merging two objects can be expressed as: ```javascript var ab = { ...a, ...b }; // merge(a, b) ``` Rationale: Spread Syntax in JSX ----------------------------------------- _Why not `<div props={props} />`?_ This reads more like the traditional attribute-value model of XML. However, it's semantics are a bit unclear. We don't actually want to allow you to set the props object itself. It's going to be a copy. It's also not setting the property named `props`. _Why not `<div {props} />`?_ Again, this is not passing the props object through. We can't allow that. So therefore it's unclear where the copying happens in this case. It's also not consistent with the other spread syntax if you want to do the same thing in objects. _Why not `<div ...props />`? Why do we need curlies?_ This becomes ambiguous for certain expressions such as `<div ...x / 5 />` where you need lots of look-ahead to solve the ambiguity. We might be able to allow a small subset of expressions to avoid the curlies in all attribute expressions, but then it would be confusing when you need it and when you don't. _Why not `<div ...{props} />`?_ This would be a reasonable but there is another use case for spread in JSX that might come up in the future... The children position. `<div> prefix {...children} suffix </div>` This would either be inconsistent in attribute position. We can't safely use the syntax `<div>Hello...{children}</div>` because `...` is so frequently used in written language, preceding an expression. _Why not allow more features that JS allow in the object position?_ You could imagine the {} escaping to JS and allowing anything that you can put in an object literal. Such as `<div {get x() { }} />` or `<div {x} />`. The main reason we don't is because we want to separate the syntax that JSX allows and the semantics that it transforms to. For example, `...` could be valid even if attributes are passed as arrays instead of objects. Besides, we don't really support getters widely and it wouldn't necessarily make sense to allow a getter to be defined inline. `<div {x} />` would be confusingly similar to `<div x />`. The first one transforms to `{ x: x }` while the second one transforms to `{ x: true }`. There's not much use for this feature beyond spreads.