ReactJS入门(三)—— 顶层API
2015-07-10 11:43
681 查看
本文基本跟着官方文档把API都走一遍,但会有实例来解释应该怎么用,木有比我更详细的API文档咯。
[b]React.createClass[/b]
参数:CONFIG(object)
创建一个ReactClass(组件类),参数是一个对象且必须带有 render 属性方法,该方法必须返回一个封闭的容器(容器内可以有其它不限结构的容器)或 null/false(表示啥都不渲染):
注意!在该方法里面,所有的 this 都会在最终调用时自动地晚绑定到当前组件的构造器上(在本文最后有个有趣的小例子说明)。
View Code
[/b]
开启或关闭 React 的触摸事件机制,传入参数 true 使 React 能处理移动设备的触摸( touch )事件:
1. React.Children.map(object children, function fn [, object context])
遍历子元素,映射为一个新的子元素集合(跟 ES5 的 Array.map 差不多):
[b]2. React.Children.forEach(object children, function fn [, object context])[/b]
遍历子元素,对每一个子元素执行回调,但不像上述的 map 那样最终返回一个新的集合(跟 ES5 的 Array.forEach 差不多):
[b]3. React.Children.count[b](object children)[/b][/b]
返回子元素的总数:
[b]4. React.Children.only[b](object children)[/b][/b]
返回仅有的一个子元素,否则(没有子元素或超过一个子元素)报错且不渲染任何东西:
话说这块其实我有些疑虑,明明可以直接使用数组的原生方法,比如 this.props.children.map/forEach ,也可以直接用 this.props.children.length 来获取总数,React 封装自己的遍历方法难道是为了polyfill IE8?
在最后说个有趣的小例子。我们知道 React.Children.map 和 React.Children.forEach 是有第三个参数(可选,用于修改上下文this)的,但我们试着执行下方的例子发现它并没按照我们的预期生效:
打印出来的是 Component 的构造器。ok,软的不行玩硬的,我们试着加俩个 bind(obj),总不至于不行了吧:
结果真的是不行,改为 call 和 apply 也都扑街~ 卧槽我读书少别欺负我啊。
后来去提 issue 询问下才知道 React.creactClass 会在后续调用自身方法时将 this 自动绑定到当前组件上,自然我们获取到的 this 总会是组件的构造器了。
因此 React.Children.map 和 React.Children.forEach 的第三个参数只要不用于 React.creactClass 的内部属性方法,都会跑的好好滴:
顶层API先总结到这边,下篇文章总结下同样很重要的组件API,共勉~
[b]React.createClass[/b]
参数:CONFIG(object)
创建一个ReactClass(组件类),参数是一个对象且必须带有 render 属性方法,该方法必须返回一个封闭的容器(容器内可以有其它不限结构的容器)或 null/false(表示啥都不渲染):
var Component = React.createClass({ render: function() { return this.props.a==1 ? <div><h1>标题</h1><p>123</p></div> : null } }); React.render( <Component a="1" />, document.body );
注意!在该方法里面,所有的 this 都会在最终调用时自动地晚绑定到当前组件的构造器上(在本文最后有个有趣的小例子说明)。
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, // 所有可以被渲染的对象:数字, // 字符串,DOM 元素或包含这些类型的数组。 optionalNode: React.PropTypes.node, // React 元素 optionalElement: React.PropTypes.element, // 用 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), // 指定Object对象内各属性的类型 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!'); } } }, /* ... */ });
View Code
[b]React.initializeTouchEvents[/b]
参数:SholdUserTouch(boolean[b])[/b]
开启或关闭 React 的触摸事件机制,传入参数 true 使 React 能处理移动设备的触摸( touch )事件:
React.initializeTouchEvents(true); var Component = React.createClass({ render : function() { return <p onTouchStart={this.props.callback}>123</p> } }); var cb = function(){ alert('touch!') }; React.render( <Component callback={cb} />, document.body )
[b]React.Children[/b]
为处理 this.props.children 这个封闭的数据结构提供了有用的工具。它有如下几个方法:1. React.Children.map(object children, function fn [, object context])
遍历子元素,映射为一个新的子元素集合(跟 ES5 的 Array.map 差不多):
var Component = React.createClass({ deal : function(child, index){ console.log(child, index); return !!index && child; //第一个li会被过滤掉,因为其索引为0 }, render : function() { return ( <ul> {React.Children.map(this.props.children, this.deal)} </ul>) } }); React.render( ( <Component> <li>0</li> <li>1</li> <li>2</li> </Component> ), document.body )
[b]2. React.Children.forEach(object children, function fn [, object context])[/b]
遍历子元素,对每一个子元素执行回调,但不像上述的 map 那样最终返回一个新的集合(跟 ES5 的 Array.forEach 差不多):
var Hello = React.createClass({ render: function() { React.Children.forEach(this.props.children, function(child){ console.log(child.props, child.key) }); return <div>Hello {this.props.name}</div>; } }); React.render(<Hello name="World"> <li myProp="test"/> <li key="blah2" myProp="test2"/> <li key="blah3"/> </Hello>, document.body);
[b]3. React.Children.count[b](object children)[/b][/b]
返回子元素的总数:
var Component = React.createClass({ render : function() { var nums = React.Children.count(this.props.children); return (<ul> <li>一共有{nums}个子元素</li> //3 {this.props.children} </ul>) } }); React.render( ( <Component> <li>0</li> <li>1</li> <li>2</li> </Component> ), document.body )
[b]4. React.Children.only[b](object children)[/b][/b]
返回仅有的一个子元素,否则(没有子元素或超过一个子元素)报错且不渲染任何东西:
var Hello = React.createClass({ render: function() { return <div>Hello {React.Children.only(this.props.children)}</div>; } }); React.render(<Hello name="World"> <span>World</span> <span>!</span> //会报错“onlyChild must be passed a children with exactly one child.” </Hello>, document.body);
话说这块其实我有些疑虑,明明可以直接使用数组的原生方法,比如 this.props.children.map/forEach ,也可以直接用 this.props.children.length 来获取总数,React 封装自己的遍历方法难道是为了polyfill IE8?
在最后说个有趣的小例子。我们知道 React.Children.map 和 React.Children.forEach 是有第三个参数(可选,用于修改上下文this)的,但我们试着执行下方的例子发现它并没按照我们的预期生效:
var obj = { num : 3 }; var Component = React.createClass({ deal : function(){ console.log(this); //it`s NOT obj }, render : function() { React.Children.forEach(this.props.children, this.deal, obj); return (<ul> {this.props.children} </ul>) } }); React.render( ( <Component> <li>0</li> <li>1</li> <li>2</li> </Component> ), document.body );
打印出来的是 Component 的构造器。ok,软的不行玩硬的,我们试着加俩个 bind(obj),总不至于不行了吧:
var obj = { num : 3 }; var Component = React.createClass({ deal : function(){ console.log(this); //it`s NOT obj }, render : function() { React.Children.forEach.bind(obj)(this.props.children, this.deal.bind(obj)); return (<ul> {this.props.children} </ul>) } }); React.render( ( <Component> <li>0</li> <li>1</li> <li>2</li> </Component> ), document.body );
结果真的是不行,改为 call 和 apply 也都扑街~ 卧槽我读书少别欺负我啊。
后来去提 issue 询问下才知道 React.creactClass 会在后续调用自身方法时将 this 自动绑定到当前组件上,自然我们获取到的 this 总会是组件的构造器了。
因此 React.Children.map 和 React.Children.forEach 的第三个参数只要不用于 React.creactClass 的内部属性方法,都会跑的好好滴:
var Component = React.createClass({ render : function() { React.Children.forEach(this.props.children, function(){ //独立的回调 console.log(this); //obj无误! }, obj); return (<ul> {this.props.children} </ul>) } });
顶层API先总结到这边,下篇文章总结下同样很重要的组件API,共勉~
相关文章推荐
- Angular vs. React - the tie breaker
- 结合 ES6+ 开发 React 组件
- 关于React在meteor钟的使用
- 高性能I/O设计模式Reactor和Proactor
- The Reactor pattern 目的和优点
- ReactiveCocoa - iOS开发的新框架
- React Native专栏 说在前面
- Netty源码解读(四)Netty与Reactor模式
- reactor和proactor模式
- reactjs 视频教程
- ReactJS学习笔记八:动画
- 用react native 做的一个推酷客户端
- 用 `react native` 模仿做的一个美团客户端首页
- 天猫Web架构/Pad客户端负责人:如何评价 React Native?
- reactor官方文档译文(2)Reactor-core模块
- ReactJS学习笔记七:表单
- React 初探
- 由ReactJS的Hello world说开来
- 深入理解JavaScript的React框架的原理
- 超级给力的JavaScript的React框架入门教程