Browse Source

Removed Q&A format

main
Connor McSheffrey 11 years ago
parent
commit
3b8c13d08d
  1. 4
      _config.yml
  2. 13
      cookbook/01-introduction-tip.md
  3. 4
      cookbook/01-introduction.md
  4. 24
      cookbook/02-inline-styles tip.md
  5. 9
      cookbook/02-inline-styles.md
  6. 31
      cookbook/03-if-else-in-JSX tip.md
  7. 9
      cookbook/03-if-else-in-JSX.md
  8. 12
      cookbook/04-self-closing-tag tip.md
  9. 9
      cookbook/04-self-closing-tag.md
  10. 12
      cookbook/05-jsx-root-node-count tip.md
  11. 7
      cookbook/05-jsx-root-node-count.md
  12. 29
      cookbook/06-style-prop-value-px tip.md
  13. 9
      cookbook/06-style-prop-value-px.md
  14. 12
      cookbook/07-children-prop-type tip.md
  15. 6
      cookbook/07-children-prop-type.md
  16. 24
      cookbook/08-controlled-input-null-value tip.md
  17. 8
      cookbook/08-controlled-input-null-value.md
  18. 12
      cookbook/09-componentWillReceiveProps-not-triggered-after-mounting-tip.md
  19. 9
      cookbook/09-componentWillReceiveProps-not-triggered-after-mounting.md
  20. 62
      cookbook/10-props-in-getInitialSate-as-anti-pattern-tip.md
  21. 17
      cookbook/10-props-in-getInitialSate-as-anti-pattern.md
  22. 40
      cookbook/11-dom-event-listeners tip.md
  23. 5
      cookbook/11-dom-event-listeners.md
  24. 45
      cookbook/12-initial-ajax tip.md
  25. 5
      cookbook/12-initial-ajax.md
  26. 29
      cookbook/13-false-in-jsx tip.md
  27. 11
      cookbook/13-false-in-jsx.md

4
_config.yml

@ -95,4 +95,6 @@ nav_cookbook:
- id: dom-event-listeners
title: DOM event listeners
- id: initial-ajax
title: Initial AJAX
title: Initial AJAX
- id: false-in-jsx
title: False In JSX

13
cookbook/01-introduction-tip.md

@ -1,13 +0,0 @@
---
id: introduction-tip
title: Cookbook Introduction
layout: cookbook
permalink: introduction-tip.html
next: inline-styles.html
---
The React.js cookbook provides common React tips, bite-sized information that can surprisingly answer lots of questions you might have had and warn you against common pitfalls.
### 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).

4
cookbook/01-introduction.md

@ -6,8 +6,8 @@ permalink: introduction.html
next: inline-styles.html
---
The React.js cookbook provides solutions for common questions asked when working with the React framework. It's written in the [cookbook format](http://shop.oreilly.com/category/series/cookbooks.do) commonly used by O'Reilly Media. See [Inline Styles](/react/cookbook/inline-styles.html) recipe as an example.
The React.js cookbook provides common React tips, bite-sized information that can surprisingly answer lots of questions you might have had and warn you against common pitfalls.
### Contributing
Submit a pull request to the [React repo](https://github.com/facebook/react) with a recipe in the cookbook format (Problem, Solution, Discussion). 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).
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).

24
cookbook/02-inline-styles tip.md

@ -1,24 +0,0 @@
---
id: inline-styles-tip
title: Inline Styles
layout: cookbook
permalink: inline-styles-tip.html
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:
```js
/** @jsx React.DOM */
var divStyle = {
color: 'white',
backgroundImage: 'url(' + imgUrl + ')',
WebkitTransition: 'all' // note the capital 'W' here
};
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".

9
cookbook/02-inline-styles.md

@ -7,11 +7,7 @@ next: if-else-in-JSX.html
prev: introduction.html
---
### Problem
You want to apply inline style to an element.
### Solution
Instead of writing a string, create 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, but as an object whose key is the camelCased version of the style name, and whose value is the style's value in string:
```js
/** @jsx React.DOM */
@ -25,5 +21,4 @@ var divStyle = {
React.renderComponent(<div style={divStyle}>Hello World!</div>, mountNode);
```
### Discussion
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 using node.style.___ in DOM. This also explains why WebkitTransition has an uppercase "W".

31
cookbook/03-if-else-in-JSX tip.md

@ -1,31 +0,0 @@
---
id: if-else-in-JSX-tip
title: If-Else in JSX
layout: cookbook
permalink: if-else-in-JSX-tip.html
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:
```js
/** @jsx React.DOM */
// this
React.renderComponent(<div id="msg">Hello World!</div>, mountNode);
// is the same as this
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:
```js
/** @jsx React.DOM */
React.renderComponent(<div id={true ? 'msg' : ''}>Hello World!</div>, mountNode);
```
Try the [JSX compiler](/react/jsx-compiler.html).

9
cookbook/03-if-else-in-JSX.md

@ -7,11 +7,7 @@ prev: inline-styles.html
next: self-closing-tag.html
---
### Problem
You want to use conditionals in JSX.
### Solution
Don't forget that JSX is really just sugar for functions:
`if-else` statements don't work inside JSX, since JSX is really just sugar for functions:
```js
/** @jsx React.DOM */
@ -32,5 +28,4 @@ What you're searching for is ternary expression:
React.renderComponent(<div id={true ? 'msg' : ''}>Hello World!</div>, mountNode);
```
### Discussion
Try the [JSX compiler](react/jsx-compiler.html).
Try the [JSX compiler](/react/jsx-compiler.html).

12
cookbook/04-self-closing-tag tip.md

@ -1,12 +0,0 @@
---
id: self-closing-tag-tip
title: Self-Closing Tag
layout: cookbook
permalink: self-closing-tag-tip.html
prev: if-else-in-JSX.html
next: jsx-root-node-count.html
---
In JSX, `<MyComponent />` alone is valid while `<MyComponent>` isn't.
Related: every React component can be self-closing: `<div/>`.

9
cookbook/04-self-closing-tag.md

@ -7,11 +7,6 @@ prev: if-else-in-JSX.html
next: jsx-root-node-count.html
---
### Problem
You're getting a parsing error (unexpected token) from JSX.
In JSX, `<MyComponent />` alone is valid while `<MyComponent>` isn't.
### Solution
One of the reasons might be that you didn't put a `/` for your self-closing tags. `<MyComponent />` is valid while `<MyComponent>` isn't.
### Discussion
In fact, every React component can be self-closing: `<div/>`.
Related: every React component can be self-closing: `<div/>`.

12
cookbook/05-jsx-root-node-count tip.md

@ -1,12 +0,0 @@
---
id: jsx-root-node-count-tip
title: Maximum number of JSX root nodes
layout: cookbook
permalink: jsx-root-node-count-tip.html
prev: self-closing-tag.html
next: style-prop-value-px.html
---
Currently, in a component's `render`, you can only return one node; if you have, say, a list of `div`s to return, you must wrap your components within a `div`, `span` or any other component.
Don't forget that JSX compiles into regular js; returning two functions doesn't really make syntactic sense. Likewise, don't put more than one child in a ternary.

7
cookbook/05-jsx-root-node-count.md

@ -7,11 +7,6 @@ prev: self-closing-tag.html
next: style-prop-value-px.html
---
### Problem
You're getting a parsing error from JSX.
Currently, in a component's `render`, you can only return one node; if you have, say, a list of `div`s to return, you must wrap your components within a `div`, `span` or any other component.
### Solution
You might have tried to return more than one node in your component's `render`. Currently, you can only return one node, meaning that you must wrap your components within, say, a `div` or a `span` (or any other component).
### Discussion
Don't forget that JSX compiles into regular js; returning two functions doesn't really make syntactic sense. Likewise, don't put more than one child in a ternary.

29
cookbook/06-style-prop-value-px tip.md

@ -1,29 +0,0 @@
---
id: style-prop-value-px-tip
title: Shorthand for specifying pixel values in style prop
layout: cookbook
permalink: style-prop-value-px-tip.html
prev: jsx-root-node-count.html
next: children-prop-type.html
---
When specifying a pixel value for your inline `style` prop, React automatically appends the string "px" for you after your number value, so this works:
```js
/** @jsx React.DOM */
var divStyle = {height: 10}; // rendered as "height:10px"
React.renderComponent(<div style={divStyle}>Hello World!</div>, mountNode);
```
See [Inline Styles](/react/docs/cookbook/inline-styles-tip.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

9
cookbook/06-style-prop-value-px.md

@ -7,11 +7,7 @@ prev: jsx-root-node-count.html
next: children-prop-type.html
---
### Problem
It's tedious to specify an inline `style` value by appending your number value with the string "px" each time.
### Solution
React automatically appends the string "px" for you after your number, so this works:
When specifying a pixel value for your inline `style` prop, React automatically appends the string "px" for you after your number value, so this works:
```js
/** @jsx React.DOM */
@ -20,8 +16,7 @@ var divStyle = {height: 10}; // rendered as "height:10px"
React.renderComponent(<div style={divStyle}>Hello World!</div>, mountNode);
```
### Discussion
See [Inline Styles](/react/docs/cookbook/inline-styles.html) for more info.
See [Inline Styles](/react/docs/cookbook/inline-styles-tip.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:

12
cookbook/07-children-prop-type tip.md

@ -1,12 +0,0 @@
---
id: children-prop-type-tip
title: Type of the children prop
layout: cookbook
permalink: children-prop-type-tip.html
prev: style-prop-value-px.html
next: controlled-input-null-value.html
---
Usually, a component's `this.props.children` is an array of components. To save an extra array allocation, it returns the component itself when there's only one.
This means accessing, for example, `this.props.children.length` might be misleading, as it could either be the `length` property of the array of children, or that of a single string component.

6
cookbook/07-children-prop-type.md

@ -7,10 +7,6 @@ prev: style-prop-value-px.html
next: controlled-input-null-value.html
---
### Problem
You get errors while manipulating `this.props.children` inside a component.
### Solution
Usually, `children` is an array of components. To save an extra array allocation, it returns the component itself when there's only one.
Usually, a component's `this.props.children` is an array of components. To save an extra array allocation, it returns the component itself when there's only one.
This means accessing, for example, `this.props.children.length` might be misleading, as it could either be the `length` property of the array of children, or that of a single string component.

24
cookbook/08-controlled-input-null-value tip.md

@ -1,24 +0,0 @@
---
id: controlled-input-null-value-tip
title: Value of null for controlled input
layout: cookbook
permalink: controlled-input-null-value-tip.html
prev: children-prop-type.html
next: componentWillReceiveProps-not-triggered-after-mounting.html
---
Specifying the `value` prop on a [controlled component](/react/docs/cookbook/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`.
The snippet below shows this phenomenon; after a second, the text becomes editable.
```js
/** @jsx React.DOM */
React.renderComponent(<input value="hi" />, mountNode);
setTimeout(function() {
React.renderComponent(<input value={null} />, mountNode);
}, 2000);
```

8
cookbook/08-controlled-input-null-value.md

@ -7,11 +7,11 @@ prev: children-prop-type.html
next: componentWillReceiveProps-not-triggered-after-mounting.html
---
### Problem
You specified a `value` parameter for your form input, but the input value can still be modified, contrary to [what you'd expect](/react/docs/cookbook/forms.html).
Specifying the `value` prop on a [controlled component](/react/docs/cookbook/forms.html) prevents the user from changing the input unless you desire so.
### Solution
You might have accidentally set `value` to `undefined` or `null`. The snippet below shows this phenomenon; after a second, the text becomes editable.
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`.
The snippet below shows this phenomenon; after a second, the text becomes editable.
```js
/** @jsx React.DOM */

12
cookbook/09-componentWillReceiveProps-not-triggered-after-mounting-tip.md

@ -1,12 +0,0 @@
---
id: componentWillReceiveProps-not-triggered-after-mounting-tip
title: componentWillReceiveProps not triggered after mounting
layout: cookbook
permalink: componentWillReceiveProps-not-triggered-after-mounting-tip.html
prev: controlled-input-null-value.html
next: props-in-getInitialSate-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/cookbook/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.

9
cookbook/09-componentWillReceiveProps-not-triggered-after-mounting.md

@ -7,11 +7,6 @@ prev: controlled-input-null-value.html
next: props-in-getInitialSate-as-anti-pattern.html
---
### Problem
`componentWillReceiveProps` isn't triggered after the node is put on scene.
`componentWillReceiveProps` isn't triggered after the node is put on scene. This is by design. Check out [other lifecycle methods](/react/docs/cookbook/component-specs.html) for the one that suits your needs.
### Solution
This is by design. Check out [other lifecycle methods](/react/docs/cookbook/component-specs.html) for the one that suits your needs.
### Discussion
`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.
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.

62
cookbook/10-props-in-getInitialSate-as-anti-pattern-tip.md

@ -1,62 +0,0 @@
---
id: props-in-getInitialSate-as-anti-pattern-tip
title: props in getInitialState is an anti-pattern
layout: cookbook
permalink: props-in-getInitialSate-as-anti-pattern-tip.html
prev: componentWillReceiveProps-not-triggered-after-mounting.html
next: dom-event-listeners.html
---
> Note:
>
> This isn't really a React-specific tip, as such anti-patterns often occur in code in general; in this case, React simply points them out more clearly.
Using props, passed down from parent, to generate state in `getInitialState` often leads to duplication of "source of truth", i.e. where the real data is. Whenever possible, compute values on-the-fly to ensure that they don't get out of sync later on and cause maintenance trouble.
Bad example:
```js
/** @jsx React.DOM */
var MessageBox = React.createClass({
getInitialState: function() {
return {nameWithQualifier: "Mr. " + this.props.name};
},
render: function() {
return <div>{this.state.nameWithQualifier}</div>;
}
});
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
```
Better:
```js
/** @jsx React.DOM */
var MessageBox = React.createClass({
render: function() {
return <div>{"Mr. " + this.props.name}</div>;
}
});
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
```
For more complex logic:
```js
/** @jsx React.DOM */
var MessageBox = React.createClass({
render: function() {
return <div>{this.getNameWithQualifier(this.props.name)}</div>;
},
getNameWithQualifier: function(name) {
return 'Mr. ' + name;
}
});
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
```

17
cookbook/10-props-in-getInitialSate-as-anti-pattern.md

@ -7,8 +7,13 @@ prev: componentWillReceiveProps-not-triggered-after-mounting.html
next: dom-event-listeners.html
---
### Problem
You're using `this.props` in a component `getInitialSate`, like so:
> Note:
>
> This isn't really a React-specific tip, as such anti-patterns often occur in code in general; in this case, React simply points them out more clearly.
Using props, passed down from parent, to generate state in `getInitialState` often leads to duplication of "source of truth", i.e. where the real data is. Whenever possible, compute values on-the-fly to ensure that they don't get out of sync later on and cause maintenance trouble.
Bad example:
```js
/** @jsx React.DOM */
@ -25,8 +30,7 @@ var MessageBox = React.createClass({
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
```
### Solution
Avoid this (see below for explanation). Compute it directly inside `render`:
Better:
```js
/** @jsx React.DOM */
@ -56,8 +60,3 @@ var MessageBox = React.createClass({
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
```
### Discussion
This isn't really a React-specific tip, as such anti-patterns often occur in code in general; in this case, React simply points them out more clearly.
Using props, passed down from parent, to generate state often leads to duplication of "source of truth", i.e. where the real data is. Whenever possible, compute values on-the-fly to ensure that they don't get out of sync later on and cause maintenance trouble.

40
cookbook/11-dom-event-listeners tip.md

@ -1,40 +0,0 @@
---
id: dom-event-listeners-tip
title: DOM event listeners in a component
layout: cookbook
permalink: dom-event-listeners-tip.html
prev: props-in-getInitialSate-as-anti-pattern.html
next: initial-ajax.html
---
> Note:
>
> This entry shows how to attach DOM events not provided by React ([check here for more info](/react/docs/cookbook/events.html)). This is good for integrations with other libraries such as jQuery.
Try to resize the window:
```js
/** @jsx React.DOM */
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>;
}
});
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.

5
cookbook/11-dom-event-listeners.md

@ -7,10 +7,6 @@ prev: props-in-getInitialSate-as-anti-pattern.html
next: initial-ajax.html
---
### Problem
You want to listen to an event inside a component.
### Solution
> Note:
>
> This entry shows how to attach DOM events not provided by React ([check here for more info](/react/docs/cookbook/events.html)). This is good for integrations with other libraries such as jQuery.
@ -41,5 +37,4 @@ var Box = React.createClass({
React.renderComponent(<Box />, mountNode);
```
### Discussion
`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.

45
cookbook/12-initial-ajax tip.md

@ -1,45 +0,0 @@
---
id: initial-ajax-tip
title: Load initial data via AJAX
layout: cookbook
permalink: initial-ajax-tip.html
prev: dom-event-listeners.html
---
Fetch data in `componentDidMount`. When they arrive, put them inside your state then render them.
This example fetches the desired Github user's lastest gist:
```js
/** @jsx React.DOM */
var UserGist = React.createClass({
getInitialState: function() {
return {
username: '',
lastGistUrl: ''
};
},
componentDidMount: function() {
$.get(this.props.source, function(result) {
var lastGist = result[0];
this.setState({
username: lastGist.user.login,
lastGistUrl: lastGist.html_url
});
}.bind(this));
},
render: function() {
return (
<div>
{this.state.username}'s last gist is
<a href={this.state.lastGistUrl}>here</a>.
</div>
);
}
});
React.renderComponent(
<UserGist source="https://api.github.com/users/octocat/gists" />, mountNode
);
```

5
cookbook/12-initial-ajax.md

@ -4,12 +4,9 @@ title: Load initial data via AJAX
layout: cookbook
permalink: initial-ajax.html
prev: dom-event-listeners.html
next: false-in-jsx.html
---
### Problem
You want to load initial ajax data.
### Solution
Fetch data in `componentDidMount`. When they arrive, put them inside your state then render them.
This example fetches the desired Github user's lastest gist:

29
cookbook/13-false-in-jsx tip.md

@ -1,29 +0,0 @@
---
id: false-in-jsx-tip
title: False in JSX
layout: cookbook
permalink: initial-ajax.html
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>`.

11
cookbook/13-false-in-jsx.md

@ -1,15 +1,13 @@
---
id: false-in-jsx
id: false-in-jsx-tip
title: False in JSX
layout: cookbook
permalink: initial-ajax.html
permalink: false-in-jsx.html
prev: initial-ajax.html
---
### Problem
How does `undefined` and `false` behave as an attribute value and as a child component?
Here's how `false` renders in different contexts:
### Solution
Renders as `id="false"`:
```js
/** @jsx React.DOM */
@ -28,5 +26,4 @@ No child:
React.renderComponent(<div>{false}</div>, mountNode);
```
### Discussion
The reason why the last 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>`.

Loading…
Cancel
Save