Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Component Lifecycle guide into React.Component reference #1

197 changes: 2 additions & 195 deletions docs/docs-old/05-reusable-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ class Greeting extends React.Component {
}
```

If you don't use ES6 yet, you may use [`React.createClass`](/react/docs/top-level-api.html#react.createclass) helper instead:
If you don't use ES6 yet, you may use the `React.createClass` helper instead:


```javascript
Expand All @@ -266,197 +266,4 @@ var Greeting = React.createClass({
});
```

The API of ES6 classes is similar to [`React.createClass`](/react/docs/top-level-api.html#react.createclass) with a few exceptions.

### Declaring Prop Types and Default Props

With functions and ES6 classes, `propTypes` and `defaultProps` are defined as properties on the components themselves:

```javascript
class Greeting extends React.Component {
// ...
}

Greeting.propTypes = {
name: React.PropTypes.string
};

Greeting.defaultProps = {
name: 'Mary'
};
```

With `React.createClass()`, you need to define `propTypes` as a property on the passed object, and `getDefaultProps()` as a function on it:

```javascript
var Greeting = React.createClass({
propTypes: {
name: React.PropTypes.string
},

getDefaultProps: function() {
return {
name: 'Mary'
};
},

// ...

});
```

### Setting the Initial State

In ES6 classes, you can define the initial state by assigning `this.state` in the constructor:

```javascript
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {count: props.initialCount};
}
// ...
}
```

With `React.createClass()`, you have to provide a separate `getInitialState` method that returns the initial state:

```javascript
var Counter = React.createClass({
getInitialState: function() {
return {count: this.props.initialCount};
},
// ...
});
```

### Autobinding

In React components declared as ES6 classes, methods follow the same semantics as regular ES6 classes. This means that they don't automatically bind `this` to the instance. You'll have to explicitly use `.bind(this)` in the constructor:

```javascript
class SayHello extends React.Component {
constructor(props) {
super(props);
// This line is important!
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
alert('Hello!');
}

render() {
// Because `this.handleClick` is bound, we can use it as an event handler.
return (
<button onClick={this.handleClick}>
Say hello
</button>
);
}
}
```

With `React.createClass()`, this is not necessary because it binds all methods:

```javascript
var SayHello = React.createClass({
handleClick: function() {
alert('Hello!');
},

render: function() {
return (
<button onClick={this.handleClick}>
Say hello
</button>
);
}
});
```

This means writing ES6 classes comes with a little more boilerplate code for event handlers, but the upside is slightly better performance in large applications.

If the boilerplate code is too unattractive to you, you may enable the **experimental** [Class Properties](https://babeljs.io/docs/plugins/transform-class-properties/) syntax proposal with Babel:


```javascript
class SayHello extends React.Component {
// WARNING: this syntax is experimental!
// Using an arrow here binds the method:
handleClick = () => {
alert('Hello!');
}

render() {
return (
<button onClick={this.handleClick}>
Say hello
</button>
);
}
}
```

Please note that the syntax above is **experimental** and the syntax may change, or the proposal might not make it into the language.

If you'd rather play it safe, you have a few options:

* Bind methods in the constructor.
* Use arrow functions, e.g. `onClick={(e) => this.handleClick(e)})`.
* Keep using `React.createClass()`.

### Mixins

>**Note:**
>
>ES6 launched without any mixin support. Therefore, there is no support for mixins when you use React with ES6 classes.
>
>**We also found numerous issues in codebases using mixins, [and don't recommend using them in the new code](/react/blog/2016/07/13/mixins-considered-harmful.html).**
>
>This section exists only for the reference.

Sometimes very different components may share some common functionality. These are sometimes called [cross-cutting concerns](https://en.wikipedia.org/wiki/Cross-cutting_concern). [`React.createClass`](/react/docs/top-level-api.html#react.createclass) lets you use a legacy `mixins` system for that.

One common use case is a component wanting to update itself on a time interval. It's easy to use `setInterval()`, but it's important to cancel your interval when you don't need it anymore to save memory. React provides [lifecycle methods](/react/docs/working-with-the-browser.html#component-lifecycle) that let you know when a component is about to be created or destroyed. Let's create a simple mixin that uses these methods to provide an easy `setInterval()` function that will automatically get cleaned up when your component is destroyed.

```javascript
var SetIntervalMixin = {
componentWillMount: function() {
this.intervals = [];
},
setInterval: function() {
this.intervals.push(setInterval.apply(null, arguments));
},
componentWillUnmount: function() {
this.intervals.forEach(clearInterval);
}
};

var TickTock = React.createClass({
mixins: [SetIntervalMixin], // Use the mixin
getInitialState: function() {
return {seconds: 0};
},
componentDidMount: function() {
this.setInterval(this.tick, 1000); // Call a method on the mixin
},
tick: function() {
this.setState({seconds: this.state.seconds + 1});
},
render: function() {
return (
<p>
React has been running for {this.state.seconds} seconds.
</p>
);
}
});

ReactDOM.render(
<TickTock />,
document.getElementById('example')
);
```

If a component is using multiple mixins and several mixins define the same lifecycle method (i.e. several mixins want to do some cleanup when the component is destroyed), all of the lifecycle methods are guaranteed to be called. Methods defined on mixins run in the order mixins were listed, followed by a method call on the component.
The API of ES6 classes is similar to `React.createClass` with a few exceptions. These are covered in [Using React without ES6](/react/docs/react-without-es6.html).
Loading