From 797577576e39fc58f46ec9f6afb17d6366a8586e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 11:01:14 -0800 Subject: [PATCH 01/12] Small cleanup to tips intro --- docs/tips/01-introduction.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/docs/tips/01-introduction.md b/docs/tips/01-introduction.md index 73e2431421..c2e86c6eae 100644 --- a/docs/tips/01-introduction.md +++ b/docs/tips/01-introduction.md @@ -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. From 7c1cf0a2dce91dc89faeaf7733751fbf15e201be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 11:12:46 -0800 Subject: [PATCH 02/12] Small cleanup to style tips --- docs/tips/02-inline-styles.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tips/02-inline-styles.md b/docs/tips/02-inline-styles.md index 80e89edd4c..1f61596a54 100644 --- a/docs/tips/02-inline-styles.md +++ b/docs/tips/02-inline-styles.md @@ -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(
Hello World!
, 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". From 684e5922e81566de41cf468d411bd447df8ab9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 12:48:26 -0800 Subject: [PATCH 03/12] Tweaks to if-else tip --- docs/tips/03-if-else-in-JSX.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/docs/tips/03-if-else-in-JSX.md b/docs/tips/03-if-else-in-JSX.md index 02b4a4092a..5a04c9f60e 100644 --- a/docs/tips/03-if-else-in-JSX.md +++ b/docs/tips/03-if-else-in-JSX.md @@ -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(
Hello World!
, mountNode); -// is the same as this + +// Is transformed to this JS: React.renderComponent(React.DOM.div({id:"msg"}, "Hello World!"), mountNode); ``` -Which means `
Hello World!
` 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(
Hello World!
, mountNode); +// This JSX: +
Hello World!
+ +// 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(
Hello World!
, mountNode); +``` + +Try using it today with the [JSX compiler](/react/jsx-compiler.html). From fe52e059b93193f062db217f11f98e88eebc4d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 12:52:44 -0800 Subject: [PATCH 04/12] Tweak for self closing tag tip --- docs/tips/04-self-closing-tag.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tips/04-self-closing-tag.md b/docs/tips/04-self-closing-tag.md index 77688f4e6e..7c0a72fa8e 100644 --- a/docs/tips/04-self-closing-tag.md +++ b/docs/tips/04-self-closing-tag.md @@ -7,7 +7,7 @@ prev: if-else-in-JSX.html next: maximum-number-of-jsx-root-nodes.html --- -In JSX, `` alone is valid while `` isn't. +In JSX, `` alone is valid while `` isn't. All tags must be closed, either with the self-closing format or with a corresponding closing tag (``). > Note: > From 49261c93920448d3b030b5778d904120299254a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 12:53:14 -0800 Subject: [PATCH 05/12] Fix broken link, formatting on px style tip --- docs/tips/06-style-props-value-px.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/tips/06-style-props-value-px.md b/docs/tips/06-style-props-value-px.md index 148057466b..233e29ff37 100644 --- a/docs/tips/06-style-props-value-px.md +++ b/docs/tips/06-style-props-value-px.md @@ -16,14 +16,14 @@ var divStyle = {height: 10}; // rendered as "height:10px" React.renderComponent(
Hello World!
, 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` From 75383c5c9973215bc834da2045518b7956247a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 12:59:03 -0800 Subject: [PATCH 06/12] Children props tip tweak --- docs/tips/07-children-props-type.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/tips/07-children-props-type.md b/docs/tips/07-children-props-type.md index 675b2f7414..8c4549acd7 100644 --- a/docs/tips/07-children-props-type.md +++ b/docs/tips/07-children-props-type.md @@ -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( - , + , 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
; From f6f3d4262b29aa4f453998f585676eb9fff6bb50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 12:59:59 -0800 Subject: [PATCH 07/12] fix broken link on controlled input tip --- docs/tips/08-controlled-input-null-value.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tips/08-controlled-input-null-value.md b/docs/tips/08-controlled-input-null-value.md index a3809654f1..37c8efb34c 100644 --- a/docs/tips/08-controlled-input-null-value.md +++ b/docs/tips/08-controlled-input-null-value.md @@ -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`. From 4a9ed4a204524afd6c6bad0d1ff50b2d6464f065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 13:06:38 -0800 Subject: [PATCH 08/12] Fix broken link on componentWillReceiveProps tip --- ...09-componentWillReceiveProps-not-triggered-after-mounting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tips/09-componentWillReceiveProps-not-triggered-after-mounting.md b/docs/tips/09-componentWillReceiveProps-not-triggered-after-mounting.md index 1a5d0b3601..b4b1cd5c1a 100644 --- a/docs/tips/09-componentWillReceiveProps-not-triggered-after-mounting.md +++ b/docs/tips/09-componentWillReceiveProps-not-triggered-after-mounting.md @@ -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. From 80ab7bf4e12e5ee8bd2f14d51f78afe74013deb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 13:09:56 -0800 Subject: [PATCH 09/12] s/Zuck/Rogers/ --- docs/tips/10-props-in-getInitialState-as-anti-pattern.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/tips/10-props-in-getInitialState-as-anti-pattern.md b/docs/tips/10-props-in-getInitialState-as-anti-pattern.md index 19f2bcd1e5..097fbc718f 100644 --- a/docs/tips/10-props-in-getInitialState-as-anti-pattern.md +++ b/docs/tips/10-props-in-getInitialState-as-anti-pattern.md @@ -27,7 +27,7 @@ var MessageBox = React.createClass({ } }); -React.renderComponent(, mountNode); +React.renderComponent(, mountNode); ``` Better: @@ -41,7 +41,7 @@ var MessageBox = React.createClass({ } }); -React.renderComponent(, mountNode); +React.renderComponent(, mountNode); ``` For more complex logic: @@ -58,5 +58,5 @@ var MessageBox = React.createClass({ } }); -React.renderComponent(, mountNode); +React.renderComponent(, mountNode); ``` From 0ebd3d92ba6626194984e53fc7de6f0445919318 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 13:11:53 -0800 Subject: [PATCH 10/12] Fix broken link, spacing on events tip --- docs/tips/11-dom-event-listeners.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/tips/11-dom-event-listeners.md b/docs/tips/11-dom-event-listeners.md index 305a0a4baa..46e577fff5 100644 --- a/docs/tips/11-dom-event-listeners.md +++ b/docs/tips/11-dom-event-listeners.md @@ -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
Current window width: {this.state.windowWidth}
; } @@ -37,4 +41,4 @@ var Box = React.createClass({ React.renderComponent(, 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. From 4367dad669084f04ed338c543e0cbb872a1ded42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 13:15:45 -0800 Subject: [PATCH 11/12] Update wording on AJAX tip --- docs/tips/12-initial-ajax.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tips/12-initial-ajax.md b/docs/tips/12-initial-ajax.md index a07f526f14..c608dc6acc 100644 --- a/docs/tips/12-initial-ajax.md +++ b/docs/tips/12-initial-ajax.md @@ -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: From c8218871602eda48b7788e3d55733e581829357d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20O=E2=80=99Shannessy?= Date: Tue, 12 Nov 2013 13:18:47 -0800 Subject: [PATCH 12/12] formatting and syntax on false in JSX tip --- docs/tips/13-false-in-jsx.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/tips/13-false-in-jsx.md b/docs/tips/13-false-in-jsx.md index f7e4e950d3..0c86bddf55 100644 --- a/docs/tips/13-false-in-jsx.md +++ b/docs/tips/13-false-in-jsx.md @@ -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(
, mountNode); ``` String "false" as input value: + ```js /** @jsx React.DOM */ React.renderComponent(, mountNode); ``` No child: + ```js /** @jsx React.DOM */ React.renderComponent(
{false}
, 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: `
{x > 1 && You have more than one item}
`. +The reason why this one doesn't render as the string `"false"` as a `div` child is to allow the more common use-case: `
{x > 1 && 'You have more than one item'}
`.