10、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" />;

我们废话不多说,我们直接来上代码看效果,还是在上面代码的基础上修改

  • 1、修改index.js
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; 


  • 2、修改Props.js
//引入所需要的类
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/tigerchain/react-lesson/tree/master/lesson02/08-props 如果大家喜欢,可以给个 star 鼓励一下

ps:此demo使用的是yarn+webpack写的,以后的demo没有特别说明都是基于yarn+webpack去编写了,并且使用的ES6语法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容