本文基本跟着官方文档把API都走一遍,但会有实例来解释应该怎么用,木有比我更详细的API文档咯。 React.createClass参数:CONFIG(object)创建一个ReactClass(组件类),参数是一个对象且必须带有 render 属性方法,该方法必须返回一个封闭的容器(容器内可以有其它不限结构的容器)或 null/false(表示啥都不渲染):varComponent =React.createClass({render:function() {returnthis.props.a==1 ?
: null}});React.render(
, document.body);React.createElement参数:TYPE(string/ReactClass),[PROPS(object)],[CHILDREN(ReactElement)]创建一个指定类型的React元素,注意第三个参数CHILDREN可以是任意个React元素:varComponent =React.createClass({render:function() {returnthis.props.a==1 ? 123
: null}});React.render(React.createElement('div',null,React.createElement('p',null,React.createElement('span',null, 'Hello,'),React.createElement('span',null, 'world,'),React.createElement( Component, {a :1}))), document.body);其实 React.createElement 是一个语法糖:varreactElement =React.createElement(type, props, children);//等价于下面两行:vardiv = React.createFactory('div');varreactDivElement = div(props, children);React.cloneElement参数:TYPE(ReactElement),[PROPS(object)],[CHILDREN(ReactElement)]克隆并返回一个新的 ReactElement (内部子元素也会跟着克隆),新返回的元素会保留有旧元素的 props、ref、key,也会集成新的 props(只要在第二个参数中有定义)。varHello =React.createClass({render:function() {varspan = VaJoy;varnewSpan = React.cloneElement(span, {b:'2'}, CNBlog);console.log(newSpan.props);returnHello {span},{newSpan}
; //Hello VaJoy,CNBlog}});React.render(, document.body);要注意的是,createElement 的第一个参数必须是字符串或 ReactClass,而在 cloneElement 里第一个参数应该是 ReactElement:varLi =React.createClass({render:function() {return{this.props.i}}});varUl =React.createClass({deal :function(child, index){//注意下面这行换成 createElement 会报错!因为child是ReactElement而不是ReactClass或字符串returnReact.cloneElement(child, {i:index});},render:function() {return{this.props.children.map(this.deal)}
;}});React.render((), document.body);React.createFactory参数:TYPE(string/ReactElement)返回一个某种类型的ReactElement工厂函数,可以利用返回的函数来创建一个ReactElement(配置 props 和 children):varComponent =React.createClass({render:function() {returnthis.props.a==1 ? 123
: null}});varp =React.createFactory(Component),ReactElementP= p({a:1}),div= React.createFactory('div'),ReactElementDiv= div(null, ReactElementP);React.render(ReactElementDiv, document.body);React.render参数:REACTELEMENT(ReactElement),CONTAINER(DOMElement),[CALLBACK(function)]渲染一个 ReactElement 到 container 指定的 DOM 中,返回一个到该组件的引用。如果提供了可选的回调函数,则该函数将会在组件渲染或者更新之后调用:varComponent =React.createClass({render:function() {returnthis.props.a==1 ? 123
: null}});varp =React.render(, document.body, function(){console.log('OK')});setTimeout(function(){console.log(p.props.a);//打印出“1”}, 2000)React.unmountComponentAtNode参数:CONTAINER(DOMElement)从 container 指定的 DOM 中移除已经挂载的 React 组件,清除相应的事件处理器和 state。如果在 container 内没有组件挂载,这个函数将什么都不做。如果组件成功移除,则返回 true;如果没有组件被移除,则返回 false:varComponent =React.createClass({render:function() {returnthis.props.a==1 ? 123
: null}});React.render(, document.body);setTimeout(function(){varisUnmount =React.unmountComponentAtNode(document.body);console.log(isUnmount);//打印出true}, 2000)React.renderToString参数:REACTELEMENT(ReactElement)React为服务端提供的一个方法,可以直接输出 ReactElement 为 HTML 字符串,将这些标记发送(比如 res.write(HTMLString))给客户端,可以获得更快的页面加载速度,并且有利于搜索引擎抓取页面,方便做 SEO(主要是百度不争气,谷歌早可以从内存中去抓最终生成的HTML内容了):varComponent =React.createClass({render:function() {returnthis.props.a==1 ? 123
: null}});varcom = ,comHTML =React.renderToString(com);console.log(comHTML);//输出“123
”React.renderToStaticMarkup参数:REACTELEMENT(ReactElement)类似 React.renderToString ,但只生成纯粹的HTML标记字符串,不会包含类似 data-reactid 之类的React属性,从而节省字节数:varComponent =React.createClass({render:function() {returnthis.props.a==1 ? 123
: null}});varcom = ,comHTML =React.renderToStaticMarkup(com);console.log(comHTML);//输出“123
”React.isValidElement参数:SOMETHING判断参数是否一个合法的 ReactElement,并返回 Boolean 值:varComponent =React.createClass({render:function() {returnthis.props.a==1 ? 123
: null}});varcom = ,com2 = '';console.log(React.isValidElement(com));//trueconsole.log(React.isValidElement(com2));//falseReact.DOM.tag参数:ATTRIBUTE(object/null),CHILDREN(string/ReactElement)常规是用于在非 JSX 下来创建 ReactElement,tag 表示相应的DOM类型(比如“div”、“p”)。另外首个参数可以定制相关的 DOM 属性(比如“name”),第二个参数表示 DOM 内的内容:vardiv = React.DOM.div({name : 'div1'}, 'HELLO ', React.DOM.span(null, WORLD));React.render(div, document.body)生成结果:HELLOWORLDReact.PropTypes用于组件内部验证传入 Props 的类型,如果传入的类型不匹配,React 会打印出警告:var Component = React.createClass({propTypes : {a : React.PropTypes.number.isRequired, //必须传入一个名为“a”、类型为number的propscallback : React.PropTypes.func //如果传入了名为“callback”的props,其类型必须是函数},render : function() {return this.props.a==1 ?123: null}});var cb = function(){alert('click!')};React.render(, document.body)上方代码中,我们虽然给组件传入了名为“a”的 props,但其类型为字符串,不是我们期望的 number 类型,故 React 会报警告:更多的 Props 期望类型可见官方例子: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!');}}},/* ... */});React.initializeTouchEvents参数:SholdUserTouch(boolean)开启或关闭 React 的触摸事件机制,传入参数 true 使 React 能处理移动设备的触摸( touch )事件:React.initializeTouchEvents(true);varComponent =React.createClass({render :function() {return123
}});varcb =function(){alert('touch!')};React.render(, document.body)React.Children为处理 this.props.children 这个封闭的数据结构提供了有用的工具。它有如下几个方法:1. React.Children.map(object children, function fn [, object context])遍历子元素,映射为一个新的子元素集合(跟 ES5 的 Array.map 差不多):varComponent =React.createClass({deal :function(child, index){console.log(child, index);return!!index && child;//第一个li会被过滤掉,因为其索引为0},render :function() {return({React.Children.map(this.props.children,this.deal)}
)}});React.render((012), document.body) 2. React.Children.forEach(object children, function fn [, object context])遍历子元素,对每一个子元素执行回调,但不像上述的 map 那样最终返回一个新的集合(跟 ES5 的 Array.forEach 差不多):varHello =React.createClass({render:function() {React.Children.forEach(this.props.children,function(child){console.log(child.props, child.key)});return
Hello {this.props.name}
;}});React.render(
, document.body); 3. React.Children.count(object children)返回子元素的总数:varComponent =React.createClass({render :function() {varnums = React.Children.count(this.props.children);return(
- 一共有{nums}个子元素
//3{this.props.children}
)}});React.render((
012), document.body) 4. React.Children.only(object children)返回仅有的一个子元素,否则(没有子元素或超过一个子元素)报错且不渲染任何东西:varHello =React.createClass({render:function() {return
Hello {React.Children.only(this.props.children)}
;}});React.render(
World! //会报错“onlyChild must be passed a children with exactly one child.”, document.body); 话说这块其实我有些疑虑,明明可以直接使用数组的原生方法,比如 this.props.children.map/forEach ,也可以直接用 this.props.children.length 来获取总数,React 封装自己的遍历方法难道是为了polyfill IE8?另外 mpa 和 forEach 的第三个参数(修改上下文this)并没生效,在stackoverflow提问过但没得到解答。 顶层API先总结到这边,下篇文章总结下同样很重要的组件API,共勉~本文链接:ReactJS入门(三)—— 顶层API,转载请注明。