[React]元件的生命週期

FreeeLinux發表於2017-12-09

元件的生命週期

元件本質上是伏態機,輸入確定,輸出一定確定。
狀態發生轉換時會觸發不同的鉤子函式,從而讓開發者有機會做出響應。
可以用事件的思國思路來理解狀態。

初始化->執行中->銷燬

初始化

getDefaultProps(只會在第一個例項初始化時被呼叫)->getInitialState->componentWillMount->render->componentDidMount

執行中

componentWillReceiveProps->shouldComponentUpdate->componentWillUpdate->render->componentDidUpdate

銷燬

componentWillUnmount

初始化階段

初始化階段可以使用的函式:

  • getDefaultProps: 只呼叫一次,例項之間共享引用
  • getInitialState: 初始化每個例項特有的狀態
  • componentWillMount: render之前最後一次修改狀態的機會
  • render: 只能訪問this.props和this.state,只有一個頂層元件(不能返回陣列),不允許修改狀態和DOM輸出
  • componentDidMount: 成功render並渲染完成真實DOM後觸發,可以修改DOM

例項演示:

    var style = {
        color: "red",
        border: "1px solid #000",
    };

    var HelloWorld = React.createClass({
        getDefaultProps: function () {
            console.log('getDefaultProps, 1')
        },
        getInitialState: function () {
            console.log('getInitialState, 2');
            return null;
        },
        componentWillMount: function () {
            console.log('componentWillMount, 3');
        },
        render: function () {
            console.log('render, 4');
            return <p ref="childp">Hello, {(function (obj) {
                if (obj.props.name) {
                    return obj.props.name;
                } else {
                    return "World";
                }
            })(this)}</p>;
        },
        componentDidMount: function () {
            console.log('componentDidMount, 5');
        }
    });
    ReactDOM.render(<div style={style}><HelloWorld></HelloWorld></div>, document.body)
    $(function () {
        var count = 0;
        var style = {
            color: "red",
            border: "1px solid #000",
        };

        var HelloWorld = React.createClass({
            getDefaultProps: function () {
                console.log('getDefaultProps, 1')
                return {name: "Tom"};
            },
            getInitialState: function () {
                console.log('getInitialState, 2');
                return {myCount: count++, ready: false};
            },
            componentWillMount: function () {
                console.log('componentWillMount, 3');
                this.setState({ready: true});
            },
            render: function () {
                console.log('render, 4');
                return <p ref="childp">Hello, {this.props.name ? this.props.name : "World"}<br/>{"" + this.state.ready + count}</p>;
            },
            componentDidMount: function () {
                console.log('componentDidMount, 5');
                $(ReactDOM.findDOMNode(this)).append('surprise!');
            }
        });
        ReactDOM.render(<div style={style}><HelloWorld></HelloWorld><br/><HelloWorld></HelloWorld></div>, document.body);
    })();

執行中階段

執行中階段可以使用的函式:
- componentWillReceiveProps: 父元件修改屬性觸發,可以修改新屬性、修改狀態
- shouldComponentUpdate: 返回false會阻止render呼叫
- componentWillUpdate: 不能合修改屬性和狀態
- render: 只能訪問this.props和this.state,只有一個頂層元件,不允許修改狀態和DOM輸出
- componentDidUpdate: 可以修改DOM

例項演示:

  var style = {
        color: "red",
        border: "1px solid #000",
    };

    var HelloWorld = React.createClass({
        componentWillReceiveProps: function () {
            console.log('componentWillReceiveProps 1');
        },
        shouldComponentUpdate: function () {
            console.log('shouldComponentUpdate 2');
            return true;
        },
        componentWillUpdate: function () {
            console.log('componentWillUpdate 3');
        },
        render: function () {
            console.log('render 4');
            return <p>Hello, {this.props.name ? this.props.name : "World"}</p>;
        },
        componentDidUpdate: function () {
            console.log('componentDidUpdate 5');
        },
    });
    var HelloUniverse = React.createClass({
        getInitialState: function () {
            return {name: ''};
        },
        handleChange: function (event) {
            this.setState({name: event.target.value});
        },
        render: function () {
            return <div>
                <HelloWorld name={this.state.name}></HelloWorld>
                <br/>
                <input type="text" onChange={this.handleChange}/>
            </div>;
        },
    });

    ReactDOM.render(<div style={style}><HelloUniverse></HelloUniverse></div>, document.body);

父元件改變子元件的屬性:

    $(document).ready(function() {
        var style = {
            color: "red",
            border: "1px solid #000",
        };

        var HelloWorld = React.createClass({
            componentWillReceiveProps: function (newProps) {
                console.log('componentWillReceiveProps 1');
                console.log(newProps);
            },
            shouldComponentUpdate: function () {
                console.log('shouldComponentUpdate 2');
                return true;
            },
            componentWillUpdate: function () {
                console.log('componentWillUpdate 3');
            },
            render: function () {
                console.log('render 4');
                return <p>Hello, {this.props.name ? this.props.name : "World"}</p>;
            },
            componentDidUpdate: function () {
                console.log('componentDidUpdate 5');
                $(ReactDOM.findDOMNode(this)).append('surprise!');
            },
        });
        var HelloUniverse = React.createClass({
            getInitialState: function () {
                return {name: ''};
            },
            handleChange: function (event) {
                this.setState({name: event.target.value});
            },
            render: function () {
                return <div>
                    <HelloWorld name={this.state.name}></HelloWorld>
                    <br/>
                    <input type="text" onChange={this.handleChange}/>
                </div>;
            },
        });

        ReactDOM.render(<div style={style}><HelloUniverse></HelloUniverse></div>, document.body);
    });

銷燬階段

    $(document).ready(function() {
        var style = {
            color: "red",
            border: "1px solid #000",
        };

        var HelloWorld = React.createClass({
            render: function () {
                console.log('render 4');
                return <p>Hello, {this.props.name ? this.props.name : "World"}</p>;
            },
            componentWillUnmount: function() {
                console.log("BOOOOOOOOOOOOOOOOOOOOOM!");
            },
        });
        var HelloUniverse = React.createClass({
            getInitialState: function () {
                return {name: ''};
            },
            handleChange: function (event) {
                this.setState({name: event.target.value});
            },
            render: function () {
                if(this.state.name == '123') {
                    return <div>123</div>;
                }
                return <div>
                    <HelloWorld name={this.state.name}></HelloWorld>
                    <br/>
                    <input type="text" onChange={this.handleChange}/>
                </div>;
            },
        });

        ReactDOM.render(<div style={style}><HelloUniverse></HelloUniverse></div>, document.body);
    });

上面示例中,一開始生成HelloWorld元件,先生成HelloWorld元件,當我們輸入123,生成

123
,相當於刪除了HelloWoorld元件。

    $(document).ready(function () {
        var style = {
            color: "red",
            border: "1px solid #000",
        };

        var HelloWorld = React.createClass({
            render: function () {
                console.log('render 4');
                return <p>Hello, {this.props.name ? this.props.name : "World"}</p>;
            },
            componentWillUnmount: function () {
                console.log("BOOOOOOOOOOOOOOOOOOOOOM!");
            },
        });
        var HelloUniverse = React.createClass({
            getInitialState: function () {
                return {name: ''};
            },
            handleChange: function (event) {
                if (event.target.value == "123") {
                    ReactDOM.unmountComponentAtNode(document.getElementsByTagName('body')[0]);  //引數為render時第二個引數節點,即下面的body
                    return;
                }
                this.setState({name: event.target.value});
            },
            render: function () {
                return <div>
                    <HelloWorld name={this.state.name}></HelloWorld>
                    <br/>
                    <input type="text" onChange={this.handleChange}/>
                </div>;
            },
        });

        ReactDOM.render(<div style={style}><HelloUniverse></HelloUniverse></div>, document.body);
    });

上面示例值接刪除了該DOM節點。

相關文章