Browse Source

props in `getInitialState` as anti-pattern

main
Cheng Lou 11 years ago
committed by Connor McSheffrey
parent
commit
65d1d23551
  1. 60
      cookbook/cb-10-props-in-getInitialSate-as-anti-pattern-tip.md
  2. 61
      cookbook/cb-10-props-in-getInitialSate-as-anti-pattern.md

60
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 <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);
```
Also works, for larger 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);
```

61
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 <div>{this.state.nameWithQualifier}</div>;
}
});
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
```
### Solution
Avoid this (see below for explanation). Compute it directly inside `render`:
```js
/** @jsx React.DOM */
var MessageBox = React.createClass({
render: function() {
return <div>{"Mr. " + this.props.name}</div>;
}
});
React.renderComponent(<MessageBox name="Zuck"/>, mountNode);
```
Or, if the logic's big, isolate it so:
```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);
```
### 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.
Loading…
Cancel
Save