[Hox库状态管理思考 二] 类实现组件的数据订阅
上文我们分析了hox 如何将 custom hooks提升到全局
阅读hox对状态管理的思考
类组件的数据订阅
前篇
首先我们来说下HOC。它是一种复用组件逻辑技巧。
高阶组件是参数为组件,返回值为新组件的函数
const EnhancedComponent = higherOrderComponent(WrappedComponent);
下面举例说明:
首先我们有一个Counter类组件如下:
interface IProps{count:number;add:()=>void;minus:()=>void;
}
class Counter extends Component<IProps> {static displayName: string;render() {const { count,add,minus } = this.propsreturn (<div><p> class count: {count}</p><button onClick={add}>add</button><button onClick={minus}>minus</button></div>)}
}
下面我们有一个需求,当Counter方法被调用时,打印更新前后的Props
function withCounter<T>(WrappedComponent: ComponentType<T>) {return (props: any) => {const prevProps = useRef();useEffect(() => {console.log('Current props', props);console.log('Prev props', prevProps.current);prevProps.current = props;}, [props])return <WrappedComponent {...props} />}
}
export default withCounter(Counter)
下面我们来分析Hox,如果将hox组件支持类组件获取数据的。
对Hox支持类组件
我们现在写一个Counter组件,该组件的状态是从props传递的(状态即从自定义hook中获取)。
class CounterView extends Component<Props> {static displayName: string;render() {const { counter } = this.propsreturn (<div><p> class count: {counter.count}</p><button onClick={counter.add}>add</button><button onClick={counter.minus}>minus</button></div>)}
}
因此我们主要将状态注入CounterView 组件中即可。
function withModel(WrappedComponent){return (props)=>{const modelProps=useModel(); // 此时获取到 {counter:{count,add,minus}}const componentProps={...props,...modelProps}return <WrappedComponent {...componentProps} />}
}// use
withModel(CounterView)
问题: useModel此时从何而来,对于withModel 是不感知被包裹组件是谁,它该获取谁的数据的。
因此只能从外部传入。
function withModel(useModel){return (WrappedComponent)=>{return (props)=>{const modelProps=useModel(); // 此时获取到 {counter:{count,add,minus}}const componentProps={...props,...modelProps}return <WrappedComponent {...componentProps} />}}
}//use
withModel(useCounterModel)(CounterView)
在开发中,我们还会面临useModel不止一个,即CounterView
可以订阅来自多个hooks数据。
下面我们处理如下:
function withModel(useModelOrUserModels){return (WrappedComponent)=>{return (props)=>{let modelProps;if (Array.isArray(useModelOrUserModels)) {const models = [];for (const useModel of useModelOrUserModels) {models.push(useModel())}modelProps = {...models}} else {modelProps=useModelOrUserModels();}const componentProps={...props,...modelProps}return <WrappedComponent {...componentProps} />}}
}
我们已经实现了一个对类组件的数据传递,我们还存在一些问题:
- 数据注入须要外部控制需要的props,因此我们加入mapModelToProps方法控制。
function withModel(useModelOrUserModels,mapModelToProps
) {return function (WrappedComponent) {const Wrapper= (props) => {let modelProps;if (Array.isArray(useModelOrUserModels)) {const models = [];for (const useModel of useModelOrUserModels) {models.push(useModel())}modelProps = mapModelToProps(models, props)} else {const model=useModelOrUserModels();modelProps = mapModelToProps(model, props);}const componentProps = {...props,...modelProps,}return <WrappedComponent {...componentProps} />}Wrapper.displayName = `${C.displayName}Wrapper`return Wrapper}
}//use
export default withModel(useCounterModel, counter => ({counter
}))(CounterView)
- 被注入的组件如果存在静态方法被包裹后获取不到了。
该问题我们可以通过手动内部转发,但要这样做,你需要知道哪些方法应该被拷贝,失去了灵活,
我们可以借助hoist-non-react-statics自行拷贝。
import hoistNonReactStatics, { NonReactStatics } from "hoist-non-react-statics";function withModel(useModelOrUserModels,mapModelToProps
) {// ...Wrapper.displayName = `${C.displayName}Wrapper`return hoistNonReactStatics(Wrapper,C);
}
总结
我们可以借助HOC
给类组件传递它所需要的数据。即在被包裹时去订阅custom hook中的数据。
[Hox库状态管理思考 二] 类实现组件的数据订阅相关推荐
- [必须要了解的React状态管理]阅读hox对状态管理的思考
对于react 状态管理已经是老生畅谈的话题,官方没有给出最佳实践因此市面上关于状态管理的探索从未停止过. 知识有限,如有不对请留言或私信 感激ing.欢迎交流
- React组件设计实践总结05 - 状态管理
今天是 520,这是本系列最后一篇文章,主要涵盖 React 状态管理的相关方案. 前几篇文章在掘金首发基本石沉大海, 没什么阅读量. 可能是文章篇幅太长了?掘金值太低了? 还是错别字太多了? 后面静 ...
- Flutter入门三部曲(3) - 数据传递/状态管理 | 掘金技术征文
Flutter数据传递 分为两种方式.一种是沿着数的方向从上向下传递状态.另一种是 从下往上传递状态值. 沿着树的方向,向下传递状态 按照Widgets Tree的方向,从上往子树和节点上传递状态. ...
- Vue状态管理vuex
转: https://www.cnblogs.com/xiaohuochai/p/7554127.html 前面的话 由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也经常逐渐增长.为 ...
- ASP.NET状态管理之一(概括篇)
每次将网页发送到服务器时,都会创建网页类的一个新实例.在传统的Web编程中,这通常意味着在每一次往返行程中,与该页及该页上的控件相关联的所有信息都会丢失.例如,如果用户将信息输入到文本框,该信息将在从 ...
- Vue的状态管理器:Vuex
无需原生开发基础,也能完美呈现京东商城.<混合开发京东商城系统,提前布局大前端>课程融合vue.Android.IOS等目前流行的前端和移动端技术,混合开发经典电商APP--京东.课程将各 ...
- vuex状态管理-逆战班
vuex 一.是什么 是一个专为vue.js应用程序开发的状态管理(共享) 二.如何用 提示:若在创建项目时没有安装vuex,则需要执行第一步:若在创建项目时,已选择安装了vuex,则可以跳过第一步, ...
- vue状态管理存取数据_vue状态管理vuex从浅入深详细讲解
1.vuex简介以及创建一个简单的仓库 vuex是专门为vue框架而设计出的一个公共数据管理框架,任何组件都可以通过状态管理仓库数据沟通,也可以统一从仓库获取数据,在比较大型的应用中,数据交互庞大的情 ...
- Vuex状态管理模式-M
Vuex Vuex 是一个专为 Vue.js 开发的状态管理模式.主要是是做数据交互,父子组件传值可以很容易办到,但是兄弟组件间传值(兄弟组件下又有父子组件),页面多并且一层嵌套一层的传值,非常麻烦, ...
最新文章
- nextcloud 中文乱码解决方案
- 乐鑫代理-启明云端分享ESP32系列教程之二:Linux搭建esp-idf环境
- Twitter的分布式自增ID算法snowflake (Java版)
- Github使用1-入门
- 深度学习-Tensorflow2.2-深度学习基础和tf.keras{1}-softmax多分类-06
- java wordcount程序_[java]wordcount程序
- Windows 7旗舰版安装Visual Studio 2013 Ultimate的系统必备及注意事项
- 【Python CheckiO 题解】Days Between
- 深度学习(莫烦 神经网络 lecture 3) Keras
- 嵌入式如何移植php,关于嵌入式web服务器的移植
- Xv6 Page Table
- 3、tiny yolov2 训练
- 7-55 查询水果价格
- NDEF格式的smart tag在Mifare UltraLight卡中的存储方式
- 期货的暴富逻辑是什么?
- 量化策略:如何利用自回归模型构建日内高频策略
- M OP N数值运算问题
- 学了python 你能干嘛
- 二进制拆弹实验详解linux,拆解二进制炸弹
- 张宏系列又又双叒叕售罄了
热门文章
- 三星Note 7惊魂48天:产品质量比创新和体验更重要
- 经验分享:如何系统学习 Web 前端技术?
- PTX JIT compiler failed
- LAMPSECURITY: CTF8-20220522
- java的 finalize() 方法
- iOS AFNetworking简介
- Latex报错(TexWork):Misplaced alignment tab character . l.13 Journal of Hygiene
- ubuntu16.04中安装Kdevelop和使用技巧
- 液体之火,酒,写的真好 ~~
- 在滴滴云 DC2 云服务器上搭建 MongoDB 实战