From 256e0bf6dfc630f2ca28cce488aaf353c7bf4c1e Mon Sep 17 00:00:00 2001 From: Jared Forsyth Date: Tue, 10 Dec 2013 11:50:44 -0700 Subject: [PATCH 1/5] rename this tip to be less confusing Using props to initialize state is completely fine; the issue is using state as a "cache" for values calculated based off of props. This title makes it more clear. --- tips/10-props-in-getInitialState-as-anti-pattern.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tips/10-props-in-getInitialState-as-anti-pattern.md b/tips/10-props-in-getInitialState-as-anti-pattern.md index 097fbc71..a9551ce3 100644 --- a/tips/10-props-in-getInitialState-as-anti-pattern.md +++ b/tips/10-props-in-getInitialState-as-anti-pattern.md @@ -1,6 +1,6 @@ --- id: props-in-getInitialState-as-anti-pattern -title: Props in getInitialState Is an Anti-Pattern +title: Using state to cache calculations is an antipattern layout: tips permalink: props-in-getInitialState-as-anti-pattern.html prev: componentWillReceiveProps-not-triggered-after-mounting.html @@ -11,7 +11,7 @@ next: dom-event-listeners.html > > 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. +Using state to cache values calculated from props (for example 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: From f3d5c90855478c9075a5cb96fec211641aa59246 Mon Sep 17 00:00:00 2001 From: Jared Forsyth Date: Tue, 10 Dec 2013 11:59:29 -0700 Subject: [PATCH 2/5] fixing capitalization --- tips/10-props-in-getInitialState-as-anti-pattern.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tips/10-props-in-getInitialState-as-anti-pattern.md b/tips/10-props-in-getInitialState-as-anti-pattern.md index a9551ce3..d9f18512 100644 --- a/tips/10-props-in-getInitialState-as-anti-pattern.md +++ b/tips/10-props-in-getInitialState-as-anti-pattern.md @@ -1,6 +1,6 @@ --- id: props-in-getInitialState-as-anti-pattern -title: Using state to cache calculations is an antipattern +title: Using State to Cache Calculations Is an Anti-Pattern layout: tips permalink: props-in-getInitialState-as-anti-pattern.html prev: componentWillReceiveProps-not-triggered-after-mounting.html From cee420b12d264bbd00eac16f030a841ea94aa56b Mon Sep 17 00:00:00 2001 From: Jared Forsyth Date: Tue, 17 Dec 2013 16:16:50 -0700 Subject: [PATCH 3/5] adding note about initializing state w/ props --- ...rops-in-getInitialState-as-anti-pattern.md | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/tips/10-props-in-getInitialState-as-anti-pattern.md b/tips/10-props-in-getInitialState-as-anti-pattern.md index d9f18512..9519761c 100644 --- a/tips/10-props-in-getInitialState-as-anti-pattern.md +++ b/tips/10-props-in-getInitialState-as-anti-pattern.md @@ -1,6 +1,6 @@ --- id: props-in-getInitialState-as-anti-pattern -title: Using State to Cache Calculations Is an Anti-Pattern +title: Props in getInitialState Is an Anti-Pattern layout: tips permalink: props-in-getInitialState-as-anti-pattern.html prev: componentWillReceiveProps-not-triggered-after-mounting.html @@ -11,7 +11,7 @@ next: dom-event-listeners.html > > 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 state to cache values calculated from props (for example 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. +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 (see [denormalization](http://en.wikipedia.org/wiki/Denormalization)). Whenever possible, compute values on-the-fly to ensure that they don't get out of sync later on and cause maintenance trouble. Javascript is plently fast for most use cases. Bad example: @@ -60,3 +60,31 @@ var MessageBox = React.createClass({ React.renderComponent(, mountNode); ``` + +**But** in situations where your component truly is stateful, using props to initialize that state is totally fine. In such cases, it can be helpful to name the prop `initialX` (or similar) to make it clear that the state will not stay in sync. + +For example: + +```js +/** @jsx React.DOM */ + +var Counter = React.createClass({ + getInitialState: function() { + return {count: this.props.initialCount}; + }, + handleClick: function() { + this.setState({ + count: this.state.count + 1 + }); + }, + render: function() { + return ( +
+ {this.state.count} +
+ ); + } +}); + +React.renderComponent(, mountNode); +``` From 49ac69b05ce1bc1a5d18c5a03c8aa58a7b97a87b Mon Sep 17 00:00:00 2001 From: Jared Forsyth Date: Tue, 17 Dec 2013 17:10:02 -0700 Subject: [PATCH 4/5] changes as requested --- ...0-props-in-getInitialState-as-anti-pattern.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tips/10-props-in-getInitialState-as-anti-pattern.md b/tips/10-props-in-getInitialState-as-anti-pattern.md index 9519761c..b63cd0b8 100644 --- a/tips/10-props-in-getInitialState-as-anti-pattern.md +++ b/tips/10-props-in-getInitialState-as-anti-pattern.md @@ -11,9 +11,9 @@ next: dom-event-listeners.html > > 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 (see [denormalization](http://en.wikipedia.org/wiki/Denormalization)). Whenever possible, compute values on-the-fly to ensure that they don't get out of sync later on and cause maintenance trouble. Javascript is plently fast for most use cases. +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: +**Bad example:** ```js /** @jsx React.DOM */ @@ -61,15 +61,15 @@ var MessageBox = React.createClass({ React.renderComponent(, mountNode); ``` -**But** in situations where your component truly is stateful, using props to initialize that state is totally fine. In such cases, it can be helpful to name the prop `initialX` (or similar) to make it clear that the state will not stay in sync. - -For example: +However, it's **not** an anti-pattern if you intentionally make it clear that synchronization's not the goal here: ```js /** @jsx React.DOM */ var Counter = React.createClass({ getInitialState: function() { + // naming it initialX clearly indicates that the only purpose + // of the passed down prop is to initialize something internal return {count: this.props.initialCount}; }, handleClick: function() { @@ -78,11 +78,7 @@ var Counter = React.createClass({ }); }, render: function() { - return ( -
- {this.state.count} -
- ); + return
{this.state.count}
; } }); From ba50af55f701a66ce1982435aa4e90f46e985420 Mon Sep 17 00:00:00 2001 From: Jared Forsyth Date: Tue, 17 Dec 2013 17:12:21 -0700 Subject: [PATCH 5/5] one liner --- tips/10-props-in-getInitialState-as-anti-pattern.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tips/10-props-in-getInitialState-as-anti-pattern.md b/tips/10-props-in-getInitialState-as-anti-pattern.md index b63cd0b8..e0f13530 100644 --- a/tips/10-props-in-getInitialState-as-anti-pattern.md +++ b/tips/10-props-in-getInitialState-as-anti-pattern.md @@ -68,14 +68,12 @@ However, it's **not** an anti-pattern if you intentionally make it clear that sy var Counter = React.createClass({ getInitialState: function() { - // naming it initialX clearly indicates that the only purpose + // naming it initialX clearly indicates that the only purpose // of the passed down prop is to initialize something internal return {count: this.props.initialCount}; }, handleClick: function() { - this.setState({ - count: this.state.count + 1 - }); + this.setState({count: this.state.count + 1}); }, render: function() { return
{this.state.count}
;