[理论]高阶组件 vs 高阶函数
首先,HOC高阶组件 vs 高阶函数:
高阶组件是:接受了一个组件作为参数,返回了另一个组件
高阶函数:接受一个函数作为参数,返回另一个函数
[理论]高阶组件的作用
复用组件逻辑
[实战] 处理空数据
在实际场景中,经常会出现一个问题就是,如果后端返回的字段,因为某些原因是null/空,那么页面上就不会展示。
为了防止数据展示的不好看,解决办法之一会是:将这些空字段统一替换成其他的,比如:‘空’ / ‘--’等。
每次在展示数据的时候,都遍历对象做空字符的替换,很累。
这个时候,我们就要复用“空字符的替换”的逻辑,写一个简单的高阶组件:
1. 需求:将空字符替换成‘--’
const withEmptyData = (WrappedComponent) => 新的组件
高阶组件:
const withEmptyData = (WrappedComponent) => {
return class extends Component {
handleProps = (props) => {
const newProps = {...props};
for (let key in props) {
newProps[key] = props[key] === null ? '空' : props[key]
}
return newProps;
}
render() {
return <WrappedComponent {...this.handleProps(this.props)}/>
}
}
}
如何使用:
const Item = ({name, age, address}) => {
return (
<div>
name: {name} --- age:{age} --- address:{address}
</div>
)
}
const WithEmptyItem = withEmptyData(Item)
展示一个最新的组件:
const mockData = {
name: 'rose',
age: null,
address: null
}
const Test = () => <WithEmptyItem {...mockData}/>
最终展示:
name:rose --- age: 空 --- address: 空
2. 需求:可以自定义当字段为空的时候显示的数据
const withEmptyData = (WrappedComponent, emptyText) => 新的组件
高阶组件:
const withEmptyData = (WrappedComponent, emptyText) => {
return class extends Component {
handleProps = (props) => {
const newProps = {...props};
for (let key in props) {
newProps[key] = props[key] === null ? emptyText : props[key]
}
return newProps;
}
render() {
return <WrappedComponent {...this.handleProps(this.props)}/>
}
}
}
如何使用:
const WithEmptyItem = withEmptyData(Item, '暂无数据')
最终展示:
name:rose --- age: 暂无数据 --- address: 暂无数据
3. 需求:双括号传参形式
const withEmptyData = emptyText => WrappedComponent => {}
还记得connect(mapState,mapDispatch)(Demo)
,这个也是一个高阶组件,这个两个括号的,我们的组件也可以改造成这个样子!
高阶组件:
const withEmptyData = emptyText => WrappedComponent => {
return class extends Component {
handleProps = (props) => {
const newProps = {...props};
for (let key in props) {
newProps[key] = props[key] === null ? emptyText : props[key]
}
return newProps;
}
render() {
return <WrappedComponent {...this.handleProps(this.props)}/>
}
}
}
如何使用:
const WithEmptyItem = withEmptyData('暂无数据')(Item)
[实战] 封装loading
当数据没有请求到之前,显示loading组件,当数据请求到了之后,显示正常的显示组件。
const withLoading = (WrappedComponent) =>{
return class extends Component{
render() {
return this.props.loading ? <div>loading....</div> : <WrappedComponent {...this.props}/>
}
}
}
const LoadingItem = withLoading(Item)
特别简单!
[合并]高阶组件上面叠加高阶组件
这是可以的,既然上面两个需求,都是必须的,那么我们尝试的把他们叠加起来!用高阶组件叠加高阶组件的形式!
const withEmptyDataItem = withEmptyData('暂无数据')(Item)
const LoadingItem = withLoading(withEmptyDataItem)
const Test = () => <LoadingItem loading={loading} {...mockData}/>
这样,空字段的展示,和loading的功能都能用上啦!
最后,了解高阶组件的背景,了解到为什么会出现高阶组件的概念,可能会更有助于我们写代码的时候的选择用它,如何用它。
当然,实战也是必不可少的!