Created
August 24, 2017 15:51
-
-
Save 0bie/15f4ba14722c27eeec991fe255246deb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Lifecycle phases: | |
// Initiialization: Defaults & initial values for `this.props` and `this.state` | |
// `getDefaultProps()` is called once and cached when the class is created | |
// We can't rely on `this.props` in `getDefaultProps()` | |
// `getInitialState()` is invoked once right before the mounting phase | |
var Counter = React.createClass({ | |
getDefaultProps: function() { | |
console.log('getDefaultProps'); | |
return { | |
title: 'Basic Counter!' | |
}; | |
}, | |
getInitialState: function() { | |
console.log('getInitialState'); | |
return { | |
count: 0 | |
}; | |
}, | |
render: function() { | |
console.log('render'); | |
return <div> | |
<h1>{this.props.title}</h1> | |
<div>{this.state.count}</div> | |
<input type="button" value="+" onClick={this.handleIncrement} /> | |
<input type="button" value="-" onClick={this.handleDecrement} /> | |
</div>; | |
}, | |
handleIncrement: function() { | |
// var newCount = this.state.count + 1; | |
// this.setState({count: newCount}); | |
this.setState((state, props) => { | |
console.log(state, props); | |
return {count: state.count + 1}; | |
}); | |
}, | |
handleDecrement: function() { | |
// var newCount = this.state.count - 1; | |
// this.setState({count: newCount}); | |
this.setState((state, props) => { | |
console.log(state, props); | |
return {count: state.count - 1}; | |
}); | |
}, | |
propTypes: { | |
title: React.PropTypes.string | |
} | |
}); | |
ReactDOM.render( | |
React.createElement(Counter), | |
document.getElementById('root') | |
); | |
// Example 2 | |
var Counter2 = React.createClass({ | |
getDefaultProps: function() { | |
console.log('getDefaultProps'); | |
return { | |
title: 'Basic Counter', | |
step: 1 | |
}; | |
}, | |
getInitialState: function() { | |
console.log('getInitialState'); | |
return { | |
count: this.props.initialCount || 0 | |
}; | |
}, | |
render: function() { | |
console.log('render'); | |
var step = this.props.step; | |
return <div> | |
<h1>{this.props.title}</h1> | |
<div>{this.state.count}</div> | |
<input type="button" value="+" onClick={this.updateCounter.bind(this, step)} /> | |
<input type="button" value="-" onClick={this.updateCounter.bind(this, -step)} /> | |
</div>; | |
}, | |
updateCounter: function(value) { | |
// var newCount = this.state.count + value; | |
// this.setState({count: newCount}); | |
this.setState((state, props) => { | |
return {count: state.count + value}; | |
}); | |
}, | |
propTypes: { | |
title: React.PropTypes.string, | |
initialCount: React.PropTypes.number, | |
step: React.PropTypes.number | |
} | |
}); | |
ReactDOM.render( | |
React.createElement(Counter2, {initialCount: 5, step: 2}), | |
document.getElementById('root') | |
); | |
// Mounting: Occurs when a component is being inserted into the DOM | |
// Has two methods: `componentWillMount()` and `componentDidMount()` | |
// `componentWillMount()` is called first and invoked once before the initial rendering occurs (before React inserts the component into the DOM) | |
// Calling `this.setState()` within `componentWillMount()` doesn't trigger a re-render | |
// `componentWillMount()` is called after `getInitialState()` and before `render()` | |
// `componentDidMount` is the second method invoked just once in this phase | |
// `componentDidMount` is called immediately after React inserts the component into the DOM | |
// `componentDidMount` is the best place for initializing other JS libraries that need access to the DOM and also for data fetching operations | |
// In this example we create a `Container` component that handles fetching data for the `Counter` component | |
var Container = React.createClass({ | |
getInitialState: function() { | |
return { | |
data: null, | |
fetching: false, | |
error: null | |
}; | |
}, | |
render: function() { | |
if (this.props.fetching) { | |
return <div>Loading...</div>; | |
} | |
if (this.props.error) { | |
return <div className="error"> | |
{this.state.error.message} | |
</div>; | |
} | |
return <Counter {...data} /> | |
}, | |
componentDidMount: function() { | |
this.setState(fetching: true); | |
Axios.get(this.props.url).then(function(res) { | |
this.setState({data: res.data, fetching: false}); | |
}).catch(function(res) { | |
this.setState({error: res.data, fetching: false}); | |
}); | |
} | |
}); | |
// Updating | |
// There are also methods that allow us to execute code relative to when a component's state or properties get updated | |
// When receiving new props from a parent they are called in the following order: | |
// `componentWillReceiveProps` => `shouldComponentUpdate` => `componentWillUpdate` => `render` => `componentDidUpdate` | |
// When the state changes via `this.setState` they are called in the following order: | |
// `shouldComponentUpdate` => `componentWillUpdate` => `render` => `componentDidUpdate` | |
// During this phase a React component is already inserted into the DOM, so these methods aren't called for the first render | |
// https://medium.com/react-ecosystem/react-components-lifecycle-ce09239010df |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment