天天看點

React系列之--props屬性

版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。

PS:轉載請注明出處

作者:TigerChain

位址:http://www.jianshu.com/p/fa81cebac3ef

本文出自TigerChain簡書

React系列教程

1、React之props屬性

我們想要在元件之間進行傳值,那麼props屬性就起到了這個作用,在React中props和state是兩個非常非常非常重要的屬性一定要掌握這兩個。(以下都是使用ES5的寫法,沒有特殊說明的都是使用ES5寫法)

Note:屬性是用于設定默念值,不改變的值使用props,而改變的值我們要使用state,我們後面章節再說

2、React之props屬性基本用法

1、基本用法
<Component data="測試props"/>
           

在Component元件中使用this.props.data就可以取得data中的值(其中data這個字段可以任意指定但是元件中的和擷取props要對應就好了)

2、廢話不多說,直接上例子

在這一節中我們使用browserify來管理js代碼,如果不知道browserify可以檢視此節

這裡假設你把browserify環境都搭建起來了

PS:本文最後的Demo是使用webpack+yarn來完成,這也是主流的方式,但是你掌握了browserify也算是多掌握一門技術。

(1)、我們建立props檔案夾,并且搭建browserify環境

具體看browserify這一節:http://www.jianshu.com/p/93a112dc62b9

(2)、建立index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>props用法</title>
  </head>
  <body>
    <div id="example"></div>
    <script src="bundle.js"></script>
  </body>
</html>
           
(3)、建立component檔案夾(在這裡我們體驗一下元件化的思想),在component檔案夾中建立一個Props.js(這就是一個元件)
//引入所需要的類
var React = require('react');
var Propos = React.createClass({
    render: function() {
        return (
            <div>
                {this.props.data}
            </div>
        );
    }
});
//将此類暴漏出去 供個部使用
module.exports = Propos;
           
(4)在props目錄下建立index.js檔案,并且使用require引入Props元件
// index.js
var React = require('react');
var ReactDOM = require('react-dom');
var Props = require('./component/Props.js') ;

ReactDOM.render(
 <Props data="我是props屬性"/>,
  document.getElementById('example')
);

           
5、我們使用browserify來将index.js轉化成bundle.js
browserify -t [ babelify ] index.js -o bundle.js
           

當然我們也可以使用watchify

6、最後我們在浏覽器中檢視結果

props_single.png

Note:props屬性不僅可以從爸爸傳遞給兒子元件,也可以從兒子傳遞給孫子,可以一直這樣傳遞下去,按需傳遞

3、多個值的傳遞

在上面我們把父元件屬性傳遞到子元件了,這是一個屬性的傳遞,那麼如何傳遞多個屬性值呢,大家可能想到了,那就定義多個屬性值就好了麼。步驟如下:

1、普通方法

  • 1、修改index.js

props_mutil.png

從圖可以看出我們隻是修改了紅色框中的Props元件中的屬性值

<Props data={"我是props屬性1"} data2={"我是屬性值2"} />
           
  • 2、修改Props.js來接收傳遞過來的值

props_propsmodify.png

同樣我們看隻是修改了紅色框聽部分,就是接收了props屬性值并且顯示

render: function() {
        return (
            <div>
                {this.props.data}
                //新增加的代碼
                <br/>
                {this.props.data2}
            </div>
        );
    }
           
  • 3、重新整理浏覽器看效果

props_mutl_result.png

從以上的結果我們确實收到了多個參數值,但是有一個問題,如果有十個參數,我就得寫十個字段屬性,20個呢,這有點扯淡吧, 有沒有什麼好的辦法呢?我能這樣問,答案是肯定的,下面我們來改造一下上面的代碼

2、推薦方法

我們使用JSX的擴充文法來傳遞屬性值,也就是...文法

return <Commponent{...this.props}more="values" />;
           

我們廢話不多說,我們直接來上代碼看效果,還是在上面代碼的基礎上修改

props_jsx_extend.png

從圖中我們可以看到,我添加了圖中紅色框中的部分,在這裡我偷偷也添加了一個test()方法,也就是說明了props不僅僅可以傳遞參數,對象也可以是一個方法,以下是修改的代碼

//定義一個屬性的對象
var propsData = {
    name:"JunJun",
    address:"china",
    height:"175cm"
}
//添加一個測試方法
function test(param){
    //把傳遞過來的參數重新拼接臧一個新的字元串
    let newParsm = param.concat("junjun") ;
    console.log(newParsm);
}

ReactDOM.render(
 <Props data={{...propsData}} data2={"我是屬性值2"}  data3={test}/>,
  document.getElementById('example')
);

           
  • 2、修改Props.js

modify_props.png

這裡也沒有什麼好說的,我們就是把傳遞過來的屬性調用了一下,讓其工作而已,以下是修改過的代碼

//測試方法點選事件
    handlerClick:function(){
        {this.props.data3("我是測試方法:")}
    },
    render: function() {
        return (
            <div>
                名字:{this.props.data.name}
                <br/>
                位址:{this.props.data.address}
                <br />
                身高:{this.props.data.height}
                <br />
                {this.props.data2}

                
                <br />
                <button onClick={this.handlerClick}>測試方法</button>
            </div>
        );
    }
           
  • 3、重新整理浏覽器,看結果

props_jsx_extends_result.png

在這裡我打開了chrome的調試工具,我們可以看到,當我們點選測試方法按鈕的時候就會調用index.js中的test()方法,列印出了我是測試的資訊,并且從浏覽器的結果中我們也可以看出,使用JSX擴充文法...傳遞過來的屬性都被接收到了。這樣是不是比前面一個一個屬性參數的傳遞友善多了,代碼也規整了。

test()方法的啟示

很好了說明了,兒子元件如何調用父親的方法,也是一種将父親方法暴漏的方式

3、預設屬性

細心的朋友可能早都發現了,在多個值的傳遞中我們發現Props.js對應的圖檔中有這麼一段代碼
//設定預設屬性,傳回一個json對象
getDefaultProps(){
        return {
            data:"預設"
        }
    },
           

這段代碼是什麼意思呢?這段代碼其實是為屬性設定預設值,也就是說一個元件沒有傳遞任何屬性的時候,我們調用了this.props.data就會使用預設的屬性值。注意這個方式是在ES5寫法中使用的,ES6寫法會有所不同

4、屬性校驗

在React中屬性是可以校驗的,比如,我們要記錄一個人的資訊,名字是必須的并且是一個字元串,年齡是一個數字,愛好是一個數組等等這些要求和規範在React中使用propTypes

1、使用方法
  • 1、在ES5中使用方法
propTypes:{
  // 可以聲明 prop 為指定的 JS 基本類型。預設
  // 情況下,這些 prop 都是可傳可不傳的。
  optionalArray: React.PropTypes.array,
  optionalBool: React.PropTypes.bool,
  optionalFunc: React.PropTypes.func,
  optionalNumber: React.PropTypes.number,
  optionalObject: React.PropTypes.object,
  optionalString: React.PropTypes.string,
  optionalSymbol: React.PropTypes.symbol,
  ....
}
           
  • 2、在ES6中使用方法
MyComponent.propTypes = {
  // You can declare that a prop is a specific JS    primitive. By default, these
  // are all optional.
  optionalArray: React.PropTypes.array,
  optionalBool: React.PropTypes.bool,
  optionalFunc: React.PropTypes.func,
  optionalNumber: React.PropTypes.number,
  optionalObject: React.PropTypes.object,
  optionalString: React.PropTypes.string,
  optionalSymbol: React.PropTypes.symbol,
  ....
  }
           
2、執行個體代碼
  • 1、我們在Props.js中添加以下代碼
//規範傳遞過來的屬性範圍
propTypes:{
    //年齡必須為數字 
    age: React.PropTypes.number,
},
           

以上規範了age屬性必須是數字類型

  • 2、修改index.js中的ReactDOM.render()方法
ReactDOM.render(
 <Props data={{...propsData}} age={"10"}  data3={test()}/>,
  document.getElementById('example')
);
           

這們這裡估計給age屬性傳了一個字元串"10",我們來看看結果

propstype.png

我們看到了浏覽器報了一個警告,意思就是說age屬性需要一個數字,你傳了一個字元串,這就校驗了props屬性,對于這個例子我們隻需要把age屬性傳遞成數字即可解決掉警告問題

5、關于this.props.children

1、this.props.children屬性

this.props屬性群組件的屬性值是一一對應的,但是有一個例外就是this.props.children,它表示的是所有子節點的屬性

2、不多說,直接上代碼

我們在上面的基礎上改代碼

  • 1、在component中建立PropsChildrenjs
var React = require('react');

var PropsChildren = React.createClass({

    /**
     * 渲染每個元素
     * @return {[type]} [description]
     */
     renderList(){
        return(
            React.Children.map(this.props.children, function (child) {
                return <li>{child}</li>;
            }));
     },
     render: function() {
        return (
            <div>
                <br />
                周遊取提this.props.children的值   
                <ul>
                {this.renderList()}
                </ul>
            </div>
            );
        }
    });


module.exports = ProposChildren; 


           
//引入所需要的類
var React = require('react');
var ProposChildren = require('./ProposChildren.js') ;

var Propos = React.createClass({
    /**
     * 用來設定預設值
     * @return {[type]} [description]
     */
    getDefaultProps(){
        return {
            data:"預設"
        }
    },
    //規範傳遞過來的屬性範圍
    propTypes:{
      //年齡必須為數字 
      age: React.PropTypes.number,
    },

    handlerClick:function(){
        {this.props.data3("我是測試方法:")}
    },

    render: function() {
        return (
            <div>

                名字:{this.props.data.name}
                <br/>
                位址:{this.props.data.address}
                <br />
                身高:{this.props.data.height}
                <br />
                年齡:{this.props.age}
                
                <br />
                <button onClick={this.handlerClick}>測試方法</button>
                //新添加的部分
                <PropsChildren>
                    <p>我是p标簽</p>
                    <h4>我是h4</h4>
                    <button>我是button</button>
                    <label>我是label</label>
                    <text>我是文本元件text</text>
                </PropsChildren>
            </div>
        );
    }

});

module.exports = Props;
           

修改的部分是

propos_children.png

  • 3、檢視結果

props_child_result.png

從圖中我們可以知道我們就周遊(使用this.props.children)取得了标簽的屬性值

到此這止我們就介紹完了props屬性

本章demo的位址

https://github.com/githubchen001/react-lesson/tree/master/lesson02/08-props 如果大家喜歡,可以給個 star 鼓勵一下