react

本文基本跟着官方文档把API都走一遍,但会有实例来解释应该怎么用,木有比我更详细的API文档咯。

React.createClass
参数: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
	);

React.createElement

参数:TYPE(string/ ReactClass ),[PROPS(object)],[CHILDREN(ReactElement)]

创建一个指定类型的React元素,注意第三个参数CHILDREN可以是任意个React元素:

var Component = React.createClass({
		render: function() {
			return this.props.a==1 ? <p>123</p> : 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 是一个语法糖:

var reactElement = React.createElement(type, props, children);
//等价于下面两行:
var div = React.createFactory('div');
var reactDivElement = div(props, children);

React.cloneElement

参数:TYPE(ReactElement),[PROPS(object)],[CHILDREN(ReactElement)]

克隆并返回一个新的 ReactElement (内部子元素也会跟着克隆),新返回的元素会保留有旧元素的 props、ref、key,也会集成新的 props(只要在第二个参数中有定义)。

var Hello = React.createClass({
            render: function() {
                var span = <span a="1">VaJoy</span>;
                var newSpan = React.cloneElement(span, {b:'2'}, <em>CNBlog</em>);
                console.log(newSpan.props);
                return <div>Hello {span},{newSpan}</div>; //Hello VaJoy,CNBlog
            }
        });

        React.render(<Hello />, document.body);

要注意的是,createElement 的第一个参数必须是字符串或 ReactClass,而在 cloneElement 里第一个参数应该是 ReactElement:

var Li = React.createClass({
			render: function() {
				return <li>{this.props.i}</li>
			}
		});
		var Ul = React.createClass({
			deal : function(child, index){
				//注意下面这行换成 createElement 会报错!因为child是ReactElement而不是ReactClass或字符串
				return React.cloneElement(child, {i:index});
			},
			render: function() {
				return <ul>{this.props.children.map(this.deal)}</ul>;
			}
		});
		React.render((
			<Ul>
				<Li i="9" />
				<Li i="8" />
				<Li i="7" />
			</Ul>
		), document.body);

React.createFactory

参数:TYPE(string/ ReactElement 

返回一个某种类型的ReactElement工厂函数,可以利用返回的函数来创建一个ReactElement(配置 props 和 children):

var Component = React.createClass({
		render: function() {
			return this.props.a==1 ? <p>123</p> : null
		}
	});
	var p = 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 中,返回一个到该组件的引用。如果提供了可选的回调函数,则该函数将会在组件渲染或者更新之后调用:

var Component = React.createClass({
		render: function() {
			return this.props.a==1 ? <p>123</p> : null
		}
	});
	var p = React.render(
		<Component a="1" />, 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:

var Component = React.createClass({
		render: function() {
			return this.props.a==1 ? <p>123</p> : null
		}
	});
	React.render(
		<Component a="1" />, document.body
	);
	setTimeout(function(){
		var isUnmount = React.unmountComponentAtNode(document.body);
		console.log(isUnmount);  //打印出true
	}, 2000)

React.renderToString
参数:REACTELEMENT(ReactElement)

React为服务端提供的一个方法,可以直接输出 ReactElement 为 HTML 字符串,将这些标记发送(比如 res.write(HTMLString))给客户端,可以获得更快的页面加载速度,并且有利于搜索引擎抓取页面,方便做 SEO(主要是百度不争气,谷歌早可以从内存中去抓最终生成的HTML内容了):

var Component = React.createClass({
		render: function() {
			return this.props.a==1 ? <p>123</p> : null
		}
	});
	var com = <Component a="1" />,
	comHTML = React.renderToString(com);
	console.log(comHTML); //输出“<p data-reactid=".0" data-react-checksum="-2122315716">123</p>”

React.renderToStaticMarkup
参数:REACTELEMENT(ReactElement)

类似 React.renderToString ,但只生成纯粹的HTML标记字符串,不会包含类似 data-reactid 之类的React属性,从而节省字节数:

var Component = React.createClass({
            render: function() {
                return this.props.a==1 ? <p>123</p> : null
            }
        });

        var com = <Component a="1" />,
            comHTML = React.renderToStaticMarkup(com);
        console.log(comHTML);  //输出“<p>123</p>”

React.isValidElement
参数:SOMETHING

判断参数是否一个合法的 ReactElement,并返回 Boolean 值:

var Component = React.createClass({
			render: function() {
				return this.props.a==1 ? <p>123</p> : null
			}
		});
		var com = <Component/>,
			com2 = '<Component/>';
		console.log(React.isValidElement(com));  //true
		console.log(React.isValidElement(com2));  //false

React.DOM.tag

参数:ATTRIBUTE(object/null  , CHILDREN (string/ReactElement)

常规是用于在非 JSX 下来创建 ReactElement,tag 表示相应的DOM类型(比如“div”、“p”)。另外首个参数可以定制相关的 DOM 属性(比如“name”),第二个参数表示 DOM 内的内容:

var div = React.DOM.div({name : 'div1'}, 'HELLO ', React.DOM.span(null, <em>WORLD</em>));
        React.render(
            div, document.body
        )

生成结果:

<div name="div1" data-reactid=".0">
  <span data-reactid=".0.0">HELLO</span>
  <span data-reactid=".0.1">
    <em data-reactid=".0.1.0">WORLD</em>
  </span>
</div>

React.PropTypes

用于组件内部验证传入 Props 的类型,如果传入的类型不匹配,React 会打印出警告:

		var Component = React.createClass({
	propTypes : {
		a : React.PropTypes.number.isRequired, //必须传入一个名为“a”、类型为number的props
		callback : React.PropTypes.func   //如果传入了名为“callback”的props,其类型必须是函数
	},
	render : function() {
		return this.props.a==1 ? <p onClick={this.props.callback}>123</p> : null
	}
});
var cb = function(){
	alert('click!')
};
React.render(
	<Component a="1" callback={cb} />, 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!');
	  }
	}
  },
  /* ... */
});
View Code

React.initializeTouchEvents

参数:SholdUserTouch(boolean  

开启或关闭 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
	)

React.Children

为处理 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
		)

2. React.Children.forEach(object children, function fn [, object context])

遍历子元素,对每一个子元素执行回调,但不像上述的 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);

3. React.Children.count(object children)

返回子元素的总数:

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
		)

4. React.Children.only(object children)

返回仅有的一个子元素,否则(没有子元素或超过一个子元素)报错且不渲染任何东西:

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?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值