react高阶组件_阶段1
作用:
个人总结的高阶组件设计的作用主要有两点, 这里直接使用装饰器方式
非装饰器使用请结合我的博文"react基础梳理_阶段1"中的"自定义高阶组件"
作用1: 加入新的自定义属性和功能(装饰器)
作用2: 行为区域的变更(状态提升)
作用1: 加入新的自定义属性和功能
思维解释:
假设我是个联邦指挥官, 我需要平复一场黑暗分子引发的叛乱, 于是我需要钢铁侠的帮助
我打电话给钢铁侠的秘书"喂? 小秘啊, 你家老刚在不在? 老铁需要援助, 国家需要你!"
小秘:“诶, 知道, 你看关键时候就得靠我们玉树临风, 英俊潇洒, 战斗力比天齐的…”
(现在我需要钢铁侠这家伙, 越牛越好 …)
于是钢铁侠大人进了他的科技仓, 科技仓自动为钢铁侠大人装备了足够战斗力的装备, 当钢铁侠大人走出科技仓, 已经变成了一个钢铁巨兽
这里做下分析: 重要角色为我(使用者), 科技仓(加工厂), 钢铁侠(功能组件)
我-> 使用钢铁侠, 不在乎钢铁侠是怎么武装自己的
科技仓-> 让人进来, 然后对人进行武装, 然后让人离开
钢铁侠-> 进入到科技仓, 出来之后就会有一些武器, 然后我直接使用武器即可
(装饰器的特性: 本身是一个加工厂, 接受一个组件, 输出一个组件)
简单案例
// 目标: 制作一个装饰器showAlertDec, 可以给任意一个react组件添加一个props属性"showAlert"
// (装饰器的加载如不会请参考我的博文react基础梳理_阶段1中的装饰器部分)
/*
使用方式:
@showAlertDec("content")
class xxx extends Components{
...
<div onCLick={this.props.showAlert}> </div>
}
*/
// 步骤1: 新建一只组件 -------------------------------------------------------------
import React, { Component } from 'react';
class Cp extends Component {
render() {
return (
<div>
我是showAlert
</div>
);
}
}
export default Cp
// 步骤2: 新建一只装饰器 -------------------------------------------------------------
// 接受一个参数
const withShowAlert= content => {
// 定义附加方法
const showAlert = () => {
alert(content)
}
// 返回装饰器格式函数, 装饰器接受一个组件, 返回一个加工过的新组件
return Comp => {
// 把props解构拷贝 增加新的方法
return props => (<Comp {...props} showAlert={showAlert}></Comp>)
}
}
// 连写版
const withShowAlertA= content => Comp => props =>
(<Comp {...props} showAlert={e => alert(content)}></Comp>)
// 使用
@withShowAlertA('我是个小白菜')
class Cp extends Component {
render() {
return (
<div onClick={this.props.showAlert}>
我是showAlert
</div>
);
}
}
// 点击div后就会弹出"我是个小白菜"
// 解释:
这里把Comp组件传入进行处理后再导出一个新的高阶组件, 这个高阶中包裹着原组件, 形成了一个组件代理
即: 装饰器(代理) 本身是个加工厂, 接受一个组件,输出一个组件, 参照此原理可以加入各种各样奇奇怪怪的东西
作用2: 行为区域的变更(状态提升)
思维解释
视图与模型分离,老生常谈的话题, 可以这样理解, 使用过vue的朋友应该了解elementui , elementui的数据校验, 数值绑定, 都在form组件中, 而非下面的form-item组件, 所有操作, 子组件只负责向form组件传值和接受form组件错误信息, 行为从form-item组件统一提升到了form组件中
请参考: https://element.faas.ele.me/#/zh-CN/component/form阶段1中不写复杂的东西, 下面简单些个小案例把, 通过装饰器把操作提升到装饰器(高阶组件)中
import React, { Component } from 'react';
const Hoc = (name,errMsg) => Comp => {
return class extends Component {
// 构建逻辑容器
constructor(props){
super(props)
this.state={name:name}
}
onChange(e){
// 根据Name来保存字段
const value = e.target.value;
// 处理组件传来的值
this.setState({
[name]:value,
[name+'ErrMSg']:value?"":errMsg
},()=>console.log(this.state))
}
render() {
return (
// 进行通信, 通过onChange方法将值保存到hoc容器中, 对值的一系列处理和验证全部在容器中进行,
// 处理过的值和相关数据通过props绑定的方式返还到组件中显示
<Comp
{...this.props}
// 设置通信通路onChange方法
onChange={e=>this.onChange(e)}
// 绑定value
submitValue={this.state[name]}
// 绑定errMsg
errMsg={this.state[name+'ErrMSg']}
/>
)
}
}
}
// 装饰目标组件
@Hoc('user',"我是错误信息")
class Cp extends Component {
render() {
const _p = this.props;
return (
<div>
<div>数据分离试验</div>
{/* 将值双向绑定到hoc容器中 */}
<input type="text" value={this.props.submitValue || ""} onChange={this.props.onChange} />
{/* 显示值 */}
<button onClick={()=>console.log(this.props.submitValue)}>commit</button>
{/* 错误信息显示容器 */}
<p>{this.props.errMsg}</p>
</div>
);
}
}
export default Cp
阶段2开始进行组件库表模式的设计总结