无状态组件
主要用于内部没有状态更新操作的组件。 同构props进行基本的数据渲染或常量展示。 该类组件职责单一,有利于组件的高复用。
const PureComponent = (props) => (
<div>
{
props.list.map((txt, index) => {
return <li key={index}>{txt}</li>
})
}
</div>
)
// 使用:
class ParentComponent extends Component {
.....
render(){
<PureComponent list={this.state.list} />
}
}
有状态组件
该类型组件可在constructor 中自定义初始状态, 并拥有完整的生命周期钩子。 可以执行一些较为负责的逻辑处理及交互展示。
class StatefulComponent extends Component {
constructor(props) {
super(props);
this.state = {
//定义状态
}
}
componentWillMount() {
//do something
}
componentDidMount() {
//do something
}
... //其他生命周期
render() {
return (
//render
);
}
}
容器组件
在实际开发中容器组件可以用来作为数据请求加工的地方。 为了使组件的职责更单一,降低组件耦合度, 引入容器组件的概念。(React Redux 的connect() 等都有用到这种组件方式)
const ProductListComtainer = React.createClass({
getInitialState(){
return {
pList: [ ]
}
},
componentDidMount() {
var _this = this;
axios.get('/api/productList').then((response) =>{
_this.setState({pList: response.data});
});
},
render(){
return (<ProductListComtainer pList={pList}></ProductListComtainer>)
}
})
高阶组件
该类组件组要用在中大型项目中,对复杂的需求,交互情况往往可以利用高阶组件写出更强复用性的组件。其本质是接收一个组件并返回一个新组件(实质是返回组件的函数)。
const HigherOrderComponent = (WrappedComponent) => {
return class WrapperComponent extends Component {
render() {
//do something with WrappedComponent
}
}
}
高阶组件在原组件的基础上,可以增加功能,属性和行为。通常的开发中我们希望组件尽量纯净或业务单一。 但通常部分组件需要增加一些辅助功能: 打印日志,获取数据或校验等, 这些公共代码会被重复写多遍。所以,可以抽象出一个高阶组件,用于给基础组件增加这些功能。
Render Callback 组件
该类型组件在组件中使用渲染回调方式, 将组件中的渲染逻辑委托给其子组件。
import { Component } from "react";
class RenderCallbackCmp extends Component {
constructor(props) {
super(props);
this.state = {
msg: "hello"
};
}
render() {
return this.props.children(this.state.msg);
}
}
const ParentComponent = () =>
(<RenderCallbackCmp>
// <p>{多个子节点时,返回Array}</p>
// <p>{多个子节点时,返回Array}</p>
{msg =>
//use the msg 返回Object 类型
<div>
{msg}
</div>}
</RenderCallbackCmp>);
关于this.props.children 值有三种情况: 如果没有子节点,值为: undefined; 如果有一个子节点, 值为:Object; 如果有多个子节点, 值为: Array。
通过使用React提供的 React.Children来处理this.props.children可以避免返回值类型不一的情况。
如:
..............
return (
React.Children.map(this.props.children, (child)=>{
return <li>{child}</li>
})
)