上文我们分析了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}  />}}
}

我们已经实现了一个对类组件的数据传递,我们还存在一些问题:

  1. 数据注入须要外部控制需要的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)
  1. 被注入的组件如果存在静态方法被包裹后获取不到了。
    该问题我们可以通过手动内部转发,但要这样做,你需要知道哪些方法应该被拷贝,失去了灵活,
    我们可以借助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库状态管理思考 二] 类实现组件的数据订阅相关推荐

  1. [必须要了解的React状态管理]阅读hox对状态管理的思考

    对于react 状态管理已经是老生畅谈的话题,官方没有给出最佳实践因此市面上关于状态管理的探索从未停止过. 知识有限,如有不对请留言或私信 感激ing.欢迎交流

  2. React组件设计实践总结05 - 状态管理

    今天是 520,这是本系列最后一篇文章,主要涵盖 React 状态管理的相关方案. 前几篇文章在掘金首发基本石沉大海, 没什么阅读量. 可能是文章篇幅太长了?掘金值太低了? 还是错别字太多了? 后面静 ...

  3. Flutter入门三部曲(3) - 数据传递/状态管理 | 掘金技术征文

    Flutter数据传递 分为两种方式.一种是沿着数的方向从上向下传递状态.另一种是 从下往上传递状态值. 沿着树的方向,向下传递状态 按照Widgets Tree的方向,从上往子树和节点上传递状态. ...

  4. Vue状态管理vuex

    转: https://www.cnblogs.com/xiaohuochai/p/7554127.html 前面的话 由于多个状态分散的跨越在许多组件和交互间各个角落,大型应用复杂度也经常逐渐增长.为 ...

  5. ASP.NET状态管理之一(概括篇)

    每次将网页发送到服务器时,都会创建网页类的一个新实例.在传统的Web编程中,这通常意味着在每一次往返行程中,与该页及该页上的控件相关联的所有信息都会丢失.例如,如果用户将信息输入到文本框,该信息将在从 ...

  6. Vue的状态管理器:Vuex

    无需原生开发基础,也能完美呈现京东商城.<混合开发京东商城系统,提前布局大前端>课程融合vue.Android.IOS等目前流行的前端和移动端技术,混合开发经典电商APP--京东.课程将各 ...

  7. vuex状态管理-逆战班

    vuex 一.是什么 是一个专为vue.js应用程序开发的状态管理(共享) 二.如何用 提示:若在创建项目时没有安装vuex,则需要执行第一步:若在创建项目时,已选择安装了vuex,则可以跳过第一步, ...

  8. vue状态管理存取数据_vue状态管理vuex从浅入深详细讲解

    1.vuex简介以及创建一个简单的仓库 vuex是专门为vue框架而设计出的一个公共数据管理框架,任何组件都可以通过状态管理仓库数据沟通,也可以统一从仓库获取数据,在比较大型的应用中,数据交互庞大的情 ...

  9. Vuex状态管理模式-M

    Vuex Vuex 是一个专为 Vue.js 开发的状态管理模式.主要是是做数据交互,父子组件传值可以很容易办到,但是兄弟组件间传值(兄弟组件下又有父子组件),页面多并且一层嵌套一层的传值,非常麻烦, ...

最新文章

  1. nextcloud 中文乱码解决方案
  2. 乐鑫代理-启明云端分享ESP32系列教程之二:Linux搭建esp-idf环境
  3. Twitter的分布式自增ID算法snowflake (Java版)
  4. Github使用1-入门
  5. 深度学习-Tensorflow2.2-深度学习基础和tf.keras{1}-softmax多分类-06
  6. java wordcount程序_[java]wordcount程序
  7. Windows 7旗舰版安装Visual Studio 2013 Ultimate的系统必备及注意事项
  8. 【Python CheckiO 题解】Days Between
  9. 深度学习(莫烦 神经网络 lecture 3) Keras
  10. 嵌入式如何移植php,关于嵌入式web服务器的移植
  11. Xv6 Page Table
  12. 3、tiny yolov2 训练
  13. 7-55 查询水果价格
  14. NDEF格式的smart tag在Mifare UltraLight卡中的存储方式
  15. 期货的暴富逻辑是什么?
  16. 量化策略:如何利用自回归模型构建日内高频策略
  17. M OP N数值运算问题
  18. 学了python 你能干嘛
  19. 二进制拆弹实验详解linux,拆解二进制炸弹
  20. 张宏系列又又双叒叕售罄了

热门文章

  1. 三星Note 7惊魂48天:产品质量比创新和体验更重要
  2. 经验分享:如何系统学习 Web 前端技术?
  3. PTX JIT compiler failed
  4. LAMPSECURITY: CTF8-20220522
  5. java的 finalize() 方法
  6. iOS AFNetworking简介
  7. Latex报错(TexWork):Misplaced alignment tab character . l.13 Journal of Hygiene
  8. ubuntu16.04中安装Kdevelop和使用技巧
  9. 液体之火,酒,写的真好 ~~
  10. 在滴滴云 DC2 云服务器上搭建 MongoDB 实战