React读书笔记-组件

本文仅作为个人学习React的笔记,文中省略了基础的知识点和术语。在阅读本文前,默认已经准备好了React的运行环境。

本文重点记录React的组件部分,且不使用ES6的特性。

如何创建一个组件?

创建一个组件使用React.createClass(object)方法,作为组件,该方法返回的变量名称必须以大写字母开头。

示例:

var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello Message!</h1>;
  }
});

在React.createClass参数必须是一个JS对象,其必须实现一个名为render方法,该方法的返回值是一个只包含一个根节点的Dom对象(可以包含自定义组件)。

组件的属性 props

组件的属性可以使用this.props来获取,该属性值来源于组件调用时的定义,属性在定义后就不能被修改,除非重新生成组件。

属性定义示例:

ReactDOM.render(
  <HelloMessage name="zsea.Message" />,
  document.getElementById('example')
);

其中,组件包含名称为name属性,可以能过this.props.name来获取。

特殊属性:props.children

该属性为组件的子对象,若子对象只有一个,该值为一个JS对象,若有多个,则为JS数组。当为JS数组时,呈现的子对象必须包含key属性。
为了简化操作,React提供了方法React.Children.map(children,function(){})用于遍历子对象,使用该方法遍历时,不需要区分是JS数组还是JS对象。

示例:

var NotesList = React.createClass({
  render: function() {
    return (
      <ol>
      {
        React.Children.map(this.props.children, function (child,_index) {
          return <li key={_index}>{child}</li>;
        })
      }
      </ol>
    );
  }
});
ReactDOM.render(
  <NotesList>
    <span>hello</span>
    <span>world</span>
  </NotesList>,
  document.body
);

属性验证 PropTypes

为保证组件被正确使用,React引入了propTypes,用于对属性进行校验,同时,React.PropTypes提供了大量的验证器来验证传入数据的有效性。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。为了性能考虑,建议只在开发环境验证 propTypes。

下面用例子来说明不同验证器的区别:

React.createClass({
  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,

    // 所有可以被渲染的对象:数字,
    // 字符串,DOM 元素或包含这些类型的数组(or fragment) 。
    optionalNode: React.PropTypes.node,

    // React 元素
    optionalElement: React.PropTypes.element,

    // 你同样可以断言一个 prop 是一个类的实例。
    // 用 JS 的 instanceof 操作符声明 prop 为类的实例。
    optionalMessage: React.PropTypes.instanceOf(Message),

    // 你可以用 enum 的方式
    // 确保你的 prop 被限定为指定值。
    optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),

    // 指定的多个对象类型中的一个
    optionalUnion: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number,
      React.PropTypes.instanceOf(Message)
    ]),

    // 指定类型组成的数组
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),

    // 指定类型的属性构成的对象
    optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),

    // 特定形状参数的对象
    optionalObjectWithShape: React.PropTypes.shape({
      color: React.PropTypes.string,
      fontSize: React.PropTypes.number
    }),

    // 你可以在任意东西后面加上 `isRequired`
    // 来确保 如果 prop 没有提供 就会显示一个警告。
    requiredFunc: React.PropTypes.func.isRequired,

    // 不可空的任意类型
    requiredAny: React.PropTypes.any.isRequired,

    // 你可以自定义一个验证器。如果验证失败需要返回一个 Error 对象。
    // 不要直接使用 `console.warn` 或抛异常,
    // 因为这在 `oneOfType` 里不起作用。
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error('Validation failed!');
      }
    }
  },
  /* ... */
});

React也提供了针对子对象的验证器

React.PropTypes.element 你可以指定仅有一个子级能被传送给组件。

var MyComponent = React.createClass({
  propTypes: {
    children: React.PropTypes.element.isRequired
  },
  render: function() {
    return (
      <div>
        {this.props.children} // 这里必须是一个元素否则就会警告
      </div>
    );
  }
});

默认属性 getDefaultProps

当父级没有传入 props 时,getDefaultProps() 可以保证 this.props.value 有默认值,注意 getDefaultProps 的结果会被缓存。得益于此,你可以直接使用 props,而不必写手动编写一些重复或无意义的代码。
该接口要求返回一个JS对象。

示例:

var ComponentWithDefaultProps = React.createClass({
  getDefaultProps: function() {
    return {
      value: 'default value'
    };
  }
});

组件的状态 state

组件的属性在被定义后,是不允放被修改的。但是,React同时也提供了组件的状态,状态是允许被在内部修改的。
获取组件状态使用this.statethis.state是一个JS对象。

示例:

var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello Message {this.state.time}!</h1>;
  }
});

其中,time为组件的一个状态。

状态的修改 setState

在语言层面,我们可以直接使用'='来修改组件的状态(this.state),但是,这种方法的修改并不能使组件触发render,修改后的状态并不能反映在WEB界面上。
Reace为我们提供了统一的状态修改方法:this.setState(state),参数state是一个JS对象,其中只需要标识需要被修改的对象,而this.state中已经存在的非同名对象不会被覆盖。该方法仅能在组件内部调用。

初始状态 getInitialState

状态是由组件内部进行控制,在没有任何方法调用前,React提供了一个接口用于组件状态的初始化:getInitialState,该接口要求返回一个JS对象。

示例:

var HelloMessage = React.createClass({
  getInitialState:function(){
      return {time:'2016-12-23'};
  },
  render: function() {
    return <h1>Hello Message {this.state.time}!</h1>;
  }
});

在getInitialState接口中,可以使用组件的属性值做为组件的状态。

示例:

var HelloMessage = React.createClass({
  getInitialState:function(){
      return {time:this.props.time};//time属性作为组件的time的状态值
  },
  render: function() {
    return <h1>Hello Message {this.state.time}!</h1>;
  }
});

总结

一个React组件,提供了两个接口、一个方法、三个对象。

两个接口

  • render
  • getInitialState

其中render用于组件的呈现,在调用方法this.setState(state)时会被自动调用。getInitialState用于返回组件内部的初始状态,可以使用属性值作为组件状态。

一个方法

  • setState(state)

该方法用于重新设置组件的状态值,并且根据需要触发render

三个对象

  • state
  • props
  • propTypes

其中state存储的组件状态,可以能过setState进行修改;

props存储的组件属性,不能被修改;同时,props包含一个特列对象:props.children,该对象中包含的时子对象。

propTypes为一个JS对象,该对象用于校验组件的属性是否正在确。

参考资料

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

推荐阅读更多精彩内容

  • 原教程内容详见精益 React 学习指南,这只是我在学习过程中的一些阅读笔记,个人觉得该教程讲解深入浅出,比目前大...
    leonaxiong阅读 2,770评论 1 18
  • 目前,react组件有三种写法,分别是es5的createClass写法,es6的class写法,以及statel...
    ZoomFunc阅读 1,561评论 0 1
  • 深入JSX date:20170412笔记原文其实JSX是React.createElement(componen...
    gaoer1938阅读 7,981评论 2 35
  • 自己最近的项目是基于react的,于是读了一遍react的文档,做了一些记录(除了REFERENCE部分还没开始读...
    潘逸飞阅读 3,190评论 1 10
  • 文/鸿运 我是一片浮云 漂浮在天地万物之间 随季节的变迁 去抒发自己的情感 春风化雨 我便滋润万物的心田 去萌发它...
    HONGYUNDANGTOU阅读 536评论 21 16