Жизненный цикл react приложений
TRANSCRIPT
React application lifecycle
1 / 31
2 / 31
React + JSX <Modal> <ModalHeader> <ModalTitle>Modal title</ModalTitle> </ModalHeader>
<ModalBody> One fine body... </ModalBody>
<ModalFooter> <Button>Close</Button> <Button type="primary">Save changes</Button> </ModalFooter>
</Modal>
3 / 31
HTML<div class="modal fade"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true" <h4 class="modal-title">Название модали</h4> </div> <div class="modal-body"> <p>One fine body…</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Закрыть</ <button type="button" class="btn btn-primary">Сохранить изменения</button> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --></div><!-- /.modal -->
4 / 31
Birth / Mounting1. Initialize / Construction
5 / 31
Birth / Mounting1. Initialize / Construction2. getDefaultProps() (React.createClass) or MyComponent.defaultProps (ES6 class)
6 / 31
Component propsimport Cowboy from 'react';
export default class Person extends React.Component { render() { return ( <div>{ this.props.name } (weapon: { this.props.weapon })</div> ); }}
<Person name="Clint Eastwood" weapon="Colt 45" />
<div>Clint Eastwood (weapon: Colt 45)</div>
7 / 31
getDefaultProps()
import React from 'react';
class Cowboy extends React.Component { render() { return ( <div>{ this.props.name } (weapon: { this.props.weapon })</div> ); }}
Person.defaultProps = { name: 'Gringo', weapon: 'unknown' };
<Person name="Clint Eastwood" />
<div>Clint Eastwood (weapon: unknown)</div>
8 / 31
For react null is value <Person name="Clint Eastwood" weapon={ null } />
<div>Clint Eastwood (weapon:)</div>
9 / 31
Birth / Mounting1. Initialize / Construction2. getDefaultProps() (React.createClass) or MyComponent.defaultProps (ES6 class)3. getInitialState() (React.createClass) or this.state = ... (ES6 constructor)
10 / 31
React stateimport React from 'react';
class Cowboy extends React.Component { constructor(props) { super(props); this.state = { isDead: false } ; } kill() { this.setState({ isDead: true }); } render() { return ( <div> {this.state.isDead ? "(RIP)" : <button onClick={() => { this.kill()}}>Kill</button>} { this.props.name } (weapon: { this.props.weapon })</div> ); }}
Person.defaultProps = { name: 'Gringo', weapon: 'unknown' };
React state 11 / 31
Birth / Mounting1. Initialize / Construction2. getDefaultProps() (React.createClass) or MyComponent.defaultProps (ES6 class)3. getInitialState() (React.createClass) or this.state = ... (ES6 constructor)4. componentWillMount()5. render()
12 / 31
render()
import React from 'react';
class Cowboy extends React.Component { constructor(props) { super(props); this.state = { isDead: false } ; } kill() { this.setState({ isDead: true }); this.state.isDead; // false } render() { return ( <div> {this.state.isDead ? "(RIP)" : <button onClick={() => { this.kill()}}>Kill</button>} { this.props.name } (weapon: { this.props.weapon }) </div> ); }}
Person.defaultProps = { name: 'Gringo', weapon: 'unknown' };
Context problem13 / 31
Resolve context problem1. Bind functions in constructor
constructor(props) {super(props);this.state = { isDead: false } ;
this.kill = this.kill.bind(this);}
2. Pass binded functions
<button onClick={this.kill.bind(this)}>Kill</button>
3. Use autobind decorator on function decoration
@autobindkill() {this.setState({ isDead: true });this.state.isDead; // false}
14 / 31
Birth / Mounting1. Initialize / Construction2. getDefaultProps() (React.createClass) or MyComponent.defaultProps (ES6 class)3. getInitialState() (React.createClass) or this.state = ... (ES6 constructor)4. componentWillMount()5. render()6. Children initialization & life cycle kickoff
15 / 31
Birth / Mounting1. Initialize / Construction2. getDefaultProps() (React.createClass) or MyComponent.defaultProps (ES6 class)3. getInitialState() (React.createClass) or this.state = ... (ES6 constructor)4. componentWillMount()5. render()6. Children initialization & life cycle kickoff7. componentDidMount()
16 / 31
17 / 31
Growth / Update1. componentWillReceiveProps()
18 / 31
Growth / Update1. componentWillReceiveProps()2. shouldComponentUpdate()
19 / 31
Growth / Update1. componentWillReceiveProps()2. shouldComponentUpdate()
20 / 31
Growth / Update1. componentWillReceiveProps()2. shouldComponentUpdate()3. componentWillUpdate()
21 / 31
Component will update every time whenstate or props changed
Default REACT implementation of componentWillUpdate:
componentWillUpdate(newProps, nextState) { const currentProps = this.props; const currentState = this.state;
return true;}
22 / 31
Growth / Update1. componentWillReceiveProps()2. shouldComponentUpdate()3. componentWillUpdate()4. render() (rerender)
23 / 31
Growth / Update1. componentWillReceiveProps()2. shouldComponentUpdate()3. componentWillUpdate()4. render() (rerender)5. Children Life cycle methods
24 / 31
25 / 31
Growth / Update1. componentWillReceiveProps()2. shouldComponentUpdate()3. componentWillUpdate()4. render() (rerender)5. Children Life cycle methods6. componentDidUpdate()
26 / 31
Death / Unmount1. componentWillUnmount()2. Children Life cycle methods3. Instance destroyed by Garbage Collector
27 / 31
JSX is not HTMLJSX code
<div> <h4> Header</h4> <button>pess me</button></div>
transforms to JS code
React.createElement( "div", null, React.createElement( "h4", null, " Header" ), React.createElement( "button", null, "pess me" ) ); }}]); 28 / 31
Test react using Jest// Link.react-test.jsimport React from 'react';import Link from '../Link.react';import renderer from 'react-test-renderer';
test('Link changes the class when hovered', () => { const component = renderer.create( <Link page="http://www.facebook.com">Facebook</Link> ); let tree = component.toJSON(); expect(tree).toMatchSnapshot();
// manually trigger the callback tree.props.onMouseEnter(); // re-rendering tree = component.toJSON(); expect(tree).toMatchSnapshot();
// manually trigger the callback tree.props.onMouseLeave(); // re-rendering tree = component.toJSON(); expect(tree).toMatchSnapshot();});
29 / 31
Jest creates shapshots/ __tests__/__snapshots__/Link.react-test.js.snap exports[̀Link changes the class when hovered 1̀] = ̀ <a className="normal" href="http://www.facebook.com" onMouseEnter={[Function]} onMouseLeave={[Function]}> Facebook </a> ̀;
exports[̀Link changes the class when hovered 2̀] = ̀ <a className="hovered" href="http://www.facebook.com" onMouseEnter={[Function]} onMouseLeave={[Function]}> Facebook </a> ̀;
exports[̀Link changes the class when hovered 3̀] = ̀ <a className="normal" href="http://www.facebook.com" onMouseEnter={[Function]} onMouseLeave={[Function]}> Facebook </a>
30 / 31
31 / 31