<react學習筆記(3)>屬性與狀態以及元件的生命週期(初始化階段)

liangsheng0111發表於2018-12-03

1.屬性和狀態

1.屬性props
  1. 含義:props = properties
  2. 屬性:一個事物的性質與關係,屬性往往是與生俱來的,無法自己改變的
  3. 屬性的兩種用法:
    a). "?"中的內容可以是:字串,物件{},陣列{[1,2,3]},變數{var}
    b). <Demo {...props} />
    var props = { one : "123", two : "456" }
  4. getDefaultProps : 設定預設屬性 第一個呼叫
2.狀態state
  1. 狀態 :事務所處的狀況
    狀況是由食物自行處理,不斷變化的。父元件與子元件都無法改變他的狀態。
  2. 狀態的用法:
    a). getInitialState : 初始化狀態
    b). setState : 更新狀態

屬性和狀態相似點 :
a). 都是純js物件,使用{}建立的物件
b). 都會觸發render更新
c). 都具有確定性,給定相同的屬性或者相同的狀態,結果是相同的

屬性和狀態的區分: 元件在執行時需要修改的資料就是狀態,所有的資料都可以變成狀態

以下是例子

//demo1 :屬性的第一種寫法
<div id="demo1"></div>
<script type="text/babel">
    var oDemo = document.getElementById("demo1"),
        Demo = React.createClass({
        render(){
            return <div>{this.props.title}</div>
        } 
    });
    ReactDOM.render(<Demo title={"Demo"}/>, oDemo);
    //this.props.title表示的就是title={"Demo"},因此在瀏覽器上會顯示出Demo這個單詞
</script>
複製程式碼
//demo2 :屬性的第二種寫法
<div id="demo2"></div>
<script type="text/babel">
    var oDemo = document.getElementById("demo2"),
        Demo = React.createClass({
            render(){
                return (<div>
                    <div>{this.props.title}</div>
                    <a {...this.props}>{this.props.title}</a>
                </div>)
    {/*
        ...this.props
        props提供的一個語法糖,可以將父元件中的全部屬性複製給子元件,
        如果是這個標籤本身擁有的這個屬性,則全部複製給子元件;反之沒有效果
    */}
                );
            }
        });
    var props = {
        title : "百度",
        href : "http://www.baidu.com"
    };
    ReactDOM.render(<Demo {...props}/>, oDemo);
</script>
複製程式碼
3.this.props.children屬性

children沒有與元件的屬性一一對應,表示元件的所有子節點,一般用於列表。

例子

<div id="demo3"></div>
<script type="text/babel">
    var oDemo = document.getElementById("demo3"),
        List = React.createClass({
            render(){
                return (<ul>
                    {   /*
                            列表項的數量以及內容不確定,在建立模板的時候菜確定。
                            利用this.props.children從父元件獲取需要的內容。
                            利用React.Children.map方法進行children的遍歷。
                            用遍歷的時候需要加{}。
                            map函式會返回值,存在child中。
                        */
                        React.Children.map(this.props.children, function(child){
                            return <li>{child}</li>;
                        });   
                    }
                </ul>);
            }   
        });
    ReactDOM.render(<List>
                        <h1>百度</h1>
                        <a href="http://www.baidu.com">http://www.baidu.com</a>
                    </List>, oDemo);
</script>
複製程式碼

demo3執行後html會變成如下:

<div id="demo3">
    <ul data-reactroot="">
        <li>
            <h1>百度</h1>
        </li>
        <li>
            <a href="http://www.baidu.com">http://www.baidu.com</a>
        </li>
    </ul>
</div>
複製程式碼

狀態state的例子

//demo4 state
<div id="demo4"></div>
<script type="text/babel">
    var oDemo = document.getElementById("demo4"),
        Demo = React.createClass({
            //設定初始的狀態 getInitialState
            getInitialState(){
                return {
                    // 這裡的值可以是一個boolean,string,function
                    onOff : true;
                };
            },
            handleClick(){
                // 通過點選事件來修改狀態值,原來的狀態值需要使用this.state獲取
                this.setState({
                    //取反
                    onOff: !this.state.onOff
                });
            },
            render(){
                return (<div onClick={this.handleClick}>{this.state.onOff ? "data1":"data2"}</div>);
                //當點選時,按照onOff屬性的改變而改變值
            }
        )};
    ReactDOM.render(<Demo />, oDemo);
</script>
複製程式碼

小案例:本地時間的顯示

//demo5
<div id="demo5"></div>
<script type="text/babel">
    var oDemo = document.getElementById("demo5"),
        Demo = React.createClass({
            //設定預設的屬性
            getDefauleProps(){
                return{
                    name : "現在的時間是:"
                };
            },
            //設定初始的狀態 getInitialState
            getInitialState(){
                return {
                    time: new Date().toLocaleTimeString(); 
                };
            },
            change(){
                // 在定時器中使用this.setState的時候需要將這個this變儲存起來
                var that = this;
                setInterval(function(){
                    that.setState({
                        time: new Date().toLocaleTimeString(); 
                    });
                },1000);
            },
            render(){
                return (<div onClick={this.change()}>{this.props.name}{this.state.time}</div>);
            }
        )};
    ReactDOM.render(<Demo name="北京時間: "/>, oDemo);
</script>
複製程式碼

2.元件的生命週期(初始化階段)

生命週期:元件的本質是狀態機,輸入確定,輸出一定確定。 一個state對應一個render,狀態轉換的時候會觸發不同的函式。

生命週期的三個階段:

  1. 初始化階段 : 設定初始的屬性與狀態
    a). getDefaultProps: 設定初始的屬性,只在第一次呼叫,例項之間共享引用。
    b). getInitialState: 設定初始的狀態。
    c). componentWillMount: 元件將要載入,render之前最後一次修改狀態的機會。
    d). render: 只能訪問this.props和this.state,只有一個頂層標籤(元件),不允許修改狀態和DOM輸出。
    e). componentDidMount: 成功render並渲染完成真實DOM之後出發,可以修改DOM,要操作DOM也必須在這個階段完成。

例子

//demo1
<div id="demo6"></div>
<script type="text/babel">
    var oDemo = document.getElementById("demo6"),
        Demo = React.createClass({
            //第一步:設定初始的屬性,只執行一次
            getDefaultProps(){
                return {
                    name1: "一個盒子",
                    title: "box"
                };
            },
            
            //第二步:設定初始的狀態(可以將屬性改成狀態)
            getInitialState(){
                return {
                    name2: this.props.name1
                };
            },
            
            //第三步:元件將要載入的時候,最後一次可以修改狀態的機會
            componentWillMount(){
                this.setState({
                    name2: "最後一次修改機會"
                });
                //第三步中是無法獲取到節點的
            },
            
            //第四步:render渲染
            render(){
                var styles = {
                    position:'absolute',
                    width: '100px',
                    height: '100px',
                    color: 'red',
                    background: 'lime'
                };
                return <div ref="box" style={styles}>{this.props.title}{this.state.name2}</div>;
            },
            
            //第五步:元件完成載入,只有在這一個階段,才可以操作DOM節點
            componentDidMount(){
                var box = this.refs.box, //父級引用子級
                    timer = null,
                    n = 0;
                    box.onclick = function(){
                        var that = this;
                        timer = setInterval(function(){
                            n++;
                            that.style.left = n + "px";
                        },100);
                    };
                
            }
        });
    ReactDOM.render(<Demo />, oDemo);
</script>
複製程式碼

效果圖: 點選後會慢慢往右移動

<react學習筆記(3)>屬性與狀態以及元件的生命週期(初始化階段)

相關文章