diff --git a/cookbook/cb-10-props-in-getInitialSate-as-anti-pattern-tip.md b/cookbook/cb-10-props-in-getInitialSate-as-anti-pattern-tip.md new file mode 100644 index 00000000..68358537 --- /dev/null +++ b/cookbook/cb-10-props-in-getInitialSate-as-anti-pattern-tip.md @@ -0,0 +1,60 @@ +--- +id: props-in-getInitialSate-as-anti-pattern-tip +title: props in getInitialState is an anti-pattern +layout: docs +permalink: props-in-getInitialSate-as-anti-pattern-tip.html +--- + +> Note: +> +> This is not 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
{this.state.nameWithQualifier}
; + } +}); + +React.renderComponent(, mountNode); +``` + +Better: + +```js +/** @jsx React.DOM */ + +var MessageBox = React.createClass({ + render: function() { + return
{"Mr. " + this.props.name}
; + } +}); + +React.renderComponent(, mountNode); +``` + +Also works, for larger logic: + +```js +/** @jsx React.DOM */ + +var MessageBox = React.createClass({ + render: function() { + return
{this.getNameWithQualifier(this.props.name)}
; + }, + getNameWithQualifier: function(name) { + return 'Mr. ' + name; + } +}); + +React.renderComponent(, mountNode); +``` diff --git a/cookbook/cb-10-props-in-getInitialSate-as-anti-pattern.md b/cookbook/cb-10-props-in-getInitialSate-as-anti-pattern.md new file mode 100644 index 00000000..fab72467 --- /dev/null +++ b/cookbook/cb-10-props-in-getInitialSate-as-anti-pattern.md @@ -0,0 +1,61 @@ +--- +id: props-in-getInitialSate-as-anti-pattern +title: props in getInitialState is an anti-pattern +layout: docs +permalink: props-in-getInitialSate-as-anti-pattern.html +--- + +### Problem +You're using `this.props` in a component `getInitialSate`, like so: + +```js +/** @jsx React.DOM */ + +var MessageBox = React.createClass({ + getInitialState: function() { + return {nameWithQualifier: "Mr. " + this.props.name}; + }, + render: function() { + return
{this.state.nameWithQualifier}
; + } +}); + +React.renderComponent(, mountNode); +``` + +### Solution +Avoid this (see below for explanation). Compute it directly inside `render`: + +```js +/** @jsx React.DOM */ + +var MessageBox = React.createClass({ + render: function() { + return
{"Mr. " + this.props.name}
; + } +}); + +React.renderComponent(, mountNode); +``` + +Or, if the logic's big, isolate it so: + +```js +/** @jsx React.DOM */ + +var MessageBox = React.createClass({ + render: function() { + return
{this.getNameWithQualifier(this.props.name)}
; + }, + getNameWithQualifier: function(name) { + return 'Mr. ' + name; + } +}); + +React.renderComponent(, mountNode); +``` + +### Discussion +This is not 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.