在v16.x版本,创建组件的主要方法React.createClass被移除了,新的创建方法(ES5)如下:
var createReactClass = require('create-react-class');
var MyComp = createReactClass({ // some code });
ES6通过class来创建,如:
import React from 'react';
import './css/color.css';
class MyComp extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
clickHandle(e) {
console.log("todo some click!")
}
render() {
return(<div className="red" onClick={this.clickHandle}>www.helloui.net</div>);
}
}
export default MyComp;
但是,便于初学者入门,前面基础几篇仍沿用v15.x的React.createClass作为创建组件的主要方法,在创建自定义组件时要注意:组件名称首字母必须为大写,否则将不通过。
组件创建
常用的创建组件的方法为React.createClass:
var HelloWorld = React.createClass({
render: function() {
return (
<div>
<h1>Hello World!</h1>
</div>
);
}
});
ReactDOM.render(
<HelloWorld />,
document.getElementById('example')
);
上例中HelloWorld就是一个简单组件。
除了React.createClass外,还可以通过使用React.createElement来创建组件,就是通过脚本嵌套一个或多个元素到一个根元素的方式创建一个组件。React.createElement的写法:
var ele = React.createElement('ul', { className: 'my-list' }, child1, child2, child3);
第一个参数是一个html标签名称字符串,也可以是一个ReactClasss,这个参数对于createElement来说是必须的。
第二个参数是该标签的属性,这个参数是可选的。
第三个参数是该元素的子节点,同样也是可选的。
React.createElement方法创建并返回一个给定类型的ReactElement元素。
var h1 = React.createElement('h1',null,"Hello World");
var div = React.createElement('div',null,h1);
ReactDOM.render(div,document.getElementById("example"));
(贴士)渲染时无需加标签的尖括号< >
React.createElement创建的元素嵌入到其他标签时,可以使用大括号{ }实现引用:
var myEle = React.createElement('div',null,'helloui');
var createReactClass = require('create-react-class');
var App = createReactClass({
getInitialState: function() {
return {}
},
render: function() {
return(
<div>{myEle}</div>
);
}
});
ReactDOM.render(<App />, document.getElementById("content"));
React.createFactory工厂方法可以批量创建组件:
var CompClass = React.createClass({
render:function(){
return (
<div>
<h1>{this.props.children}{this.props.text}</h1>
</div>
);
}
});
var Comp = React.createFactory(CompClass);
var HelloWorld = React.createElement('div',null,Comp({text:'First Text Content'},'Hello World1'),Comp(null,'Hello World2'));
ReactDOM.render(HelloWorld,document.getElementById("example"));
(贴士)上例中通过React.createFactory创建了两个结构一样但内容不同的组件Hello World1和Hello World2,CompClass仅作为结构提供方,而且Hello World1还附带了入参对象{text:'First Text Content'}。
(贴士)在v16.x和v15.x,React.createElement和React.createFactory的API并没有改变。
获取入参对象可以通过this.props获取:
var HelloWorld = React.createClass({
render:function(){
return <h1>Hello {this.props.name}</h1>
}
});
ReactDOM.render(
<HelloWorld name="Dear" />,
document.getElementById("example")
);
把参数设置为属性attr,然后在组件渲染中通过{this.props.attr}的方式读取,上例中{this.props.name}的值就是“Dear”。
组件的检测
创建组件后,我们可以通过React.isValidElement()方法来检测组件的有效性,目的是为了增强代码的健壮性,确定传入是否为React Element,防止渲染出错。要注意,React.isValidElement()只对React创建的组件检测有效,对已被转化为纯文本的组件脚本无效。比如说,若React创建的组件放在服务端渲染,返回到前端的将会是一串脚本字符串,React.isValidElement()对这类脚本字符串检测总为false。
var HelloWorld = React.createClass({
render: function() {
return (
<div>
<h1>Hello World!</h1>
</div>
);
}
});
ReactDOM.render(
<HelloWorld />,
document.getElementById('example')
);
var helloWorld_HtmlText = ReactDOMServer.renderToString(<HelloWorld />);
console.log(React.isValidElement(<HelloWorld />)); // true
console.log(React.isValidElement(helloWorld_HtmlText)); // fase
组件的移除
ReactDOM提供的移除组件:
ReactDOM.unmountComponentAtNode(document.getElementById('example'));
我们也可以用原生js脚本移除组件:
var f = document.getElementById("example");
var childs = f.childNodes;
for(var i = 0; i < childs.length; i++) {
f.removeChild(childs[i]);
}
另外,ReactDOM提供了对节点的查找方法:ReactDOM.findDOMNode
<script type="text/babel">
var HelloWorld = React.createClass({
render: function() {
return (
<div>
<h1>Hello World!</h1>
</div>
);
}
});
var reactEle = ReactDOM.render(
<HelloWorld />,
document.getElementById('example')
);
console.log(ReactDOM.findDOMNode(reactEle));
</script>
查找到的节点对象,可以配合jQuery进行使用。
组件的隐藏
在极少数情况下,你可能希望隐藏组件,即使它被其他组件渲染。让 render 方法返回 null 而不是它的渲染结果即可实现。在下面的例子中,<WarningBanner /> 根据属性 warn 的值条件渲染。如果 warn 的值是 false,则组件不会渲染。
// 渲染函数
function WarningBanner(props) {
if (!props.warn) {
return null;
}
return (
<div className="warning">
Warning!
</div>
);
}
// 组件
<WarningBanner warn={this.state.showWarning} />
组件的 render 方法返回 null 并不会影响该组件生命周期方法的回调。例如,componentWillUpdate 和 componentDidUpdate 依然可以被调用。还有另一种写法如下:
<div>
{showHeader && <Header />}
<Content />
</div>
这在根据条件来确定是否渲染React元素时非常有用。以下的JSX只会在showHeader为true时渲染<Header />组件。