react系列(3)元件建立、檢測、移除和隱藏
在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 />元件。