Render方法返回类型
render方法既可以返回一个元素,也可以返回一个数组或者字符串。
返回数组示例代码:
import React from 'react'
class ListComponent extends React.Component {
render() {
return([
<li key="A">A</li>,
<li key="B">B</li>,
<li key="C">C</li>,
<li key="D">D</li>
]);
}
}
export default ListComponent;
返回字符串示例代码:
import React from 'react'
class StringComponent extends React.Component {
render() {
return("这是字符串~");
}
}
export default StringComponent;
错误处理
React16 提供的错误处理机制,默认情况下,当组件中抛出异常错误时,发生错误的组件会从组件树中被卸载,从而避免整个应用发生错误而崩溃。
React16还提供了错误边界,错误边界就是能够捕获子组件的错误并对其做出优雅处理的组件。
优雅处理可以是输出错误日志、显示出错误提示等。
定义了componentDidCatch(error, info)这个方法的组件将成为一个错误边界。
定义错误边界组件:
import React from 'react'
class ErrorBoundaryComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
hasError: false
}
}
//定义错误边界方法
componentDidCatch(error, info) {
this.setState({hasError: true});
console.log(error, info);
}
render() {
//如果发生错误则返回错误提示
if(this.state.hasError) {
return <h1>哎呀,发生了一点错误</h1>
}
//返回子组件
return this.props.children;
}
}
export default ErrorBoundaryComponent;
使用错误边界组件:
import React from 'react'
import ErrorBoundaryComponent from './ErrorBoundaryComponent';
const Profile = ({user}) => <div>用户名:{user.name}</div>
class TestErrorComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
user: {name : "React"}
}
}
//模拟错误
onClick = () => {
this.setState({user: null});
}
render() {
return(
<div>
<ErrorBoundaryComponent>
<Profile user={this.state.user}/>
</ErrorBoundaryComponent>
<button onClick={this.onClick}>更新</button>
</div>
);
}
}
export default TestErrorComponent;
使用create-react-app创建的项目,当程序出错时,create-react-app会在页面上创建一个显示错误信息的浮层,如要观察ErrorBoundary的效果需要关闭浮层。
Portals特性
Portals特性可以把组件渲染到当前组件树以外的DOM节点上,这个特性典型的应用场景是渲染应用的全局弹窗,使用Portals后,任意组件都可以将弹框组件渲染到根节点上,以方便弹框的显示。
Portals特性用到了一个API:ReactDOM.createPortals(child, container);
该API的第一个参数child是可以被渲染的React节点,第二个参数是一个DOM元素,child将被挂载到这个DOM节点。
弹框示例代码:
import React from 'react'
import ReactDOM from 'react-dom';
const styles = {
MyModal: {
backgroundColor: "red"
}
};
class MyModal extends React.Component {
constructor(props) {
super(props);
//创建一个节点
this.container = document.createElement("div");
document.body.appendChild(this.container);
}
componentWillUnmount() {
document.body.removeChild(this.container);
}
render() {
return ReactDOM.createPortal(
<div className="modal" style={styles.MyModal}>
<span className="close" onClick={this.props.onClose}>
×
</span>
<div className="content">
{this.props.children}
</div>
</div>,
this.container
);
}
}
export default MyModal;
使用弹框:
import React from 'react'
import MyModal from './MyModal';
class TestMyModal extends React.Component {
constructor(props) {
super(props);
this.state = {
showModal: true
}
}
closeModal = () => {
this.setState({showModal: false});
}
render() {
return(
<div>
<h2>这是一段文字</h2>
{
this.state.showModal && (
<MyModal onClose={this.closeModal}>弹窗内容</MyModal>
)
}
</div>
);
}
}
export default TestMyModal;