Merge pull request #20 from zpao/tips

Updates to tips
This commit is contained in:
Connor McSheffrey
2013-11-14 11:17:34 -08:00
12 changed files with 55 additions and 37 deletions
+2 -4
View File
@@ -8,8 +8,6 @@ next: inline-styles.html
The React tips section provides bite-sized information that can answer lots of questions you might have and warn you against common pitfalls.
### Contributing
## Contributing
Submit a pull request to the [React repo](https://github.com/facebook/react) following the cookbook entries' style. If you have a recipe that needs review prior to submitting a PR you can find help in the [#reactjs IRC on freenode](irc://chat.freenode.net/reactjs) or the [reactjs Google group](http://groups.google.com/group/reactjs). Also, check the [Tips Wiki][1] for entries in-progress and general guidelines on writing React tips.
[1]: https://github.com/facebook/react/wiki/Tips-(Previously-Cookbook)
Submit a pull request to the [React repository](https://github.com/facebook/react) following the [current tips](https://github.com/facebook/react/tree/master/docs) entries' style. If you have a recipe that needs review prior to submitting a PR you can find help in the [#reactjs channel on freenode](irc://chat.freenode.net/reactjs) or the [reactjs Google group](http://groups.google.com/group/reactjs). Also, check the [Tips Wiki](https://github.com/facebook/react/wiki/Tips-(Previously-Cookbook)) for entries in-progress and general guidelines on writing React tips.
+2 -2
View File
@@ -7,7 +7,7 @@ next: if-else-in-JSX.html
prev: introduction.html
---
In React, inline styles are not specified as a string, but as an object whose key is the camelCased version of the style name, and whose value is the style's value in string:
In React, inline styles are not specified as a string. Instead they are specified with an object whose key is the camelCased version of the style name, and whose value is the style's value, usually a string ([more on that later](/react/tips/style-props-value-px.html)):
```js
/** @jsx React.DOM */
@@ -21,4 +21,4 @@ var divStyle = {
React.renderComponent(<div style={divStyle}>Hello World!</div>, mountNode);
```
Style keys are camelCased in order to be consistent with accessing the properties using node.style.___ in DOM. This also explains why WebkitTransition has an uppercase "W".
Style keys are camelCased in order to be consistent with accessing the properties on DOM nodes from JS (e.g. `node.style.backgroundImage`). Vendor prefixes should begin with a capital letter. This is why `WebkitTransition` has an uppercase "W".
+19 -8
View File
@@ -7,25 +7,36 @@ prev: inline-styles.html
next: self-closing-tag.html
---
`if-else` statements don't work inside JSX, since JSX is really just sugar for functions:
`if-else` statements don't work inside JSX. This is because JSX is just syntactic sugar for function calls and object construction. Take this basic example:
```js
/** @jsx React.DOM */
// this
// This JSX:
React.renderComponent(<div id="msg">Hello World!</div>, mountNode);
// is the same as this
// Is transformed to this JS:
React.renderComponent(React.DOM.div({id:"msg"}, "Hello World!"), mountNode);
```
Which means `<div id={if (true){ 'msg' }}>Hello World!</div>` doesn't make sense, as (if it worked) it would be compiled down to something like this `React.DOM.div({id: if (true){ 'msg' }}, "Hello World!")`, which isn't valid JS.
What you're searching for is ternary expression:
This means that `if` statements don't fit in. Take this example:
```js
/** @jsx React.DOM */
React.renderComponent(<div id={true ? 'msg' : ''}>Hello World!</div>, mountNode);
// This JSX:
<div id={if (condition) { 'msg' }}>Hello World!</div>
// Is transformed to this JS:
React.DOM.div({id: if (condition) { 'msg' }}, "Hello World!");
```
Try the [JSX compiler](/react/jsx-compiler.html).
That's not valid JS. You probably want to make use of a ternary expression:
```js
/** @jsx React.DOM */
React.renderComponent(<div id={condition ? 'msg' : ''}>Hello World!</div>, mountNode);
```
Try using it today with the [JSX compiler](/react/jsx-compiler.html).
+1 -1
View File
@@ -7,7 +7,7 @@ prev: if-else-in-JSX.html
next: maximum-number-of-jsx-root-nodes.html
---
In JSX, `<MyComponent />` alone is valid while `<MyComponent>` isn't.
In JSX, `<MyComponent />` alone is valid while `<MyComponent>` isn't. All tags must be closed, either with the self-closing format or with a corresponding closing tag (`</MyComponent>`).
> Note:
>
+8 -8
View File
@@ -16,14 +16,14 @@ var divStyle = {height: 10}; // rendered as "height:10px"
React.renderComponent(<div style={divStyle}>Hello World!</div>, mountNode);
```
See [Inline Styles](/react/docs/tips/inline-styles-tip.html) for more info.
See [Inline Styles](/react/tips/inline-styles.html) for more info.
Sometimes you _do_ want to keep the CSS properties unitless. Here's a list of properties that won't get the automatic "px" suffix:
- fillOpacity
- fontWeight
- lineHeight
- opacity
- orphans
- zIndex
- zoom
- `fillOpacity`
- `fontWeight`
- `lineHeight`
- `opacity`
- `orphans`
- `zIndex`
- `zoom`
+7 -5
View File
@@ -7,7 +7,7 @@ prev: style-props-value-px.html
next: controlled-input-null-value.html
---
Usually, a component's `this.props.children` is an array of components:
Usually, a component's children (`this.props.children`) is an array of components:
```js
/** @jsx React.DOM */
@@ -22,21 +22,23 @@ var GenericWrapper = React.createClass({
});
React.renderComponent(
<GenericWrapper><span/><span/><span/></GenericWrapper>,
<GenericWrapper><span/><span/><span/></GenericWrapper>,
mountNode
);
```
To save an extra array allocation, it returns the component itself _without the array wrapper_ when there's only one child.
However, when there is only a single child, `this.props.children` will be the single child component itself _without the array wrapper_. This saves an array allocation.
```js
/** @jsx React.DOM */
var GenericWrapper = React.createClass({
componentDidMount: function() {
// **warning**: yields 5 for length of the string 'hello', not 1 for the
console.log(Array.isArray(this.props.children)); // => false
// warning: yields 5 for length of the string 'hello', not 1 for the
// length of the non-existant array wrapper!
console.log(this.props.children.length);
console.log(this.props.children.length);
},
render: function() {
return <div />;
+1 -1
View File
@@ -7,7 +7,7 @@ prev: children-props-type.html
next: componentWillReceiveProps-not-triggered-after-mounting.html
---
Specifying the `value` prop on a [controlled component](/react/docs/tips/forms.html) prevents the user from changing the input unless you desire so.
Specifying the `value` prop on a [controlled component](/react/docs/forms.html) prevents the user from changing the input unless you desire so.
You might have run into a problem where `value` is specified, but the input can still be changed without consent. In this case, you might have accidentally set `value` to `undefined` or `null`.
@@ -7,6 +7,6 @@ prev: controlled-input-null-value.html
next: props-in-getInitialState-as-anti-pattern.html
---
`componentWillReceiveProps` isn't triggered after the node is put on scene. This is by design. Check out [other lifecycle methods](/react/docs/tips/component-specs.html) for the one that suits your needs.
`componentWillReceiveProps` isn't triggered after the node is put on scene. This is by design. Check out [other lifecycle methods](/react/docs/component-specs.html) for the one that suits your needs.
The reason for that is because `componentWillReceiveProps` often handles the logic of comparing with the old props and acting upon changes; not triggering it at mounting (where there are no old props) helps in defining what the method does.
@@ -27,7 +27,7 @@ var MessageBox = React.createClass({
}
});
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
React.renderComponent(<MessageBox name="Rogers"/>, mountNode);
```
Better:
@@ -41,7 +41,7 @@ var MessageBox = React.createClass({
}
});
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
React.renderComponent(<MessageBox name="Rogers"/>, mountNode);
```
For more complex logic:
@@ -58,5 +58,5 @@ var MessageBox = React.createClass({
}
});
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
React.renderComponent(<MessageBox name="Rogers"/>, mountNode);
```
+6 -2
View File
@@ -9,7 +9,7 @@ next: initial-ajax.html
> Note:
>
> This entry shows how to attach DOM events not provided by React ([check here for more info](/react/docs/tips/events.html)). This is good for integrations with other libraries such as jQuery.
> This entry shows how to attach DOM events not provided by React ([check here for more info](/react/docs/events.html)). This is good for integrations with other libraries such as jQuery.
Try to resize the window:
@@ -20,15 +20,19 @@ var Box = React.createClass({
getInitialState: function() {
return {windowWidth: window.innerWidth};
},
handleResize: function(e) {
this.setState({windowWidth: window.innerWidth});
},
componentDidMount: function() {
window.addEventListener('resize', this.handleResize);
},
componentWillUnmount: function() {
window.removeEventListener('resize', this.handleResize);
},
render: function() {
return <div>Current window width: {this.state.windowWidth}</div>;
}
@@ -37,4 +41,4 @@ var Box = React.createClass({
React.renderComponent(<Box />, mountNode);
```
`componentDidMount` is called after the component's mounted and has a DOM representation. This is often a place where you'd attach generic DOM events.
`componentDidMount` is called after the component is mounted and has a DOM representation. This is often a place where you would attach generic DOM events.
+1 -1
View File
@@ -7,7 +7,7 @@ prev: dom-event-listeners.html
next: false-in-jsx.html
---
Fetch data in `componentDidMount`. When they arrive, put them inside your state then render them.
Fetch data in `componentDidMount`. When the response arrives, store the data in state, triggering a render to update your UI.
This example fetches the desired Github user's lastest gist:
+4 -1
View File
@@ -9,21 +9,24 @@ prev: initial-ajax.html
Here's how `false` renders in different contexts:
Renders as `id="false"`:
```js
/** @jsx React.DOM */
React.renderComponent(<div id={false} />, mountNode);
```
String "false" as input value:
```js
/** @jsx React.DOM */
React.renderComponent(<input value={false} />, mountNode);
```
No child:
```js
/** @jsx React.DOM */
React.renderComponent(<div>{false}</div>, mountNode);
```
The reason why this one doesn't render as the string `"false"` as a `div` child is to allow the more common use-case: `<div>{x > 1 && You have more than one item}</div>`.
The reason why this one doesn't render as the string `"false"` as a `div` child is to allow the more common use-case: `<div>{x > 1 && 'You have more than one item'}</div>`.