深入浅出 React 的 HOC 以及的 Render Props
当然,这句话分分钟都要被产品打脸,天天喊着改需求,老哥,这里改下可好? 那么这次我们来讲讲 React 里的高级组件React 高级组件有两种方式:
高阶组件首先来说说高阶组件,它不是 React 的提供的 API,它是模式,一种增强组件的模式,简单来说其实就是高阶函数,高阶函数大家应该不陌生
而所谓的高阶组件也就是传入一个现有组件作为参数,返回一个新的组件,高阶租价也分为代理方式和继承方式 import React from ‘react‘; function addNameProp(WrapperComponent) { return class extends React.Component { render() { const { name,...props } = this.props; return <WrapperComponent {...props} name={name || ‘cnyballk‘} />; } }; } export default addNameProp; 在上面的代码里我们定义了一个 addNameProp。 函数,它的作用就是为没有传入 name 的 prop 传入的组件添加一个 name 的 prop ,然后渲染出来 这个高阶组件就完成了对传入组件的增强,这也是一个代理方式的高阶组件, 那么继承方式是怎么样的呢 import React from ‘react‘; function addNameProp(WrapperComponent) { return class extends WrapperComponent { render() { this.props = { ...this.props,name: this.props.name || ‘canyballk‘,}; return super.render(); } }; } export default addNameProp; 和上面的高阶组件 一样的效果,而继承模式和代理模式最大的区别就是一个是返回传入的组件,一个是调用继承的父组件的 render 方法
如果我们用过 react-redux 的 connect 也就知道 connect 也是一个代理模式的高阶组件
@Wrapper class Index extends Component { ...略 } emmmm...这个涉及到 js 的装饰器,各位自己去搜来学习哈 Render Props那么我们已经认识了高阶组件的重用方法,也认识到了高阶组件的优点。 但是高阶组件的缺点是什么呢? 相信你们也能看到了,我们传递一个 name 的 Prop ,那是不是得传入的组件能够处理才可以,而且还有命名的冲突危险,毕竟有些组件的 props 命名各有不同,或者说子组件需要同一份数据处理方式却不一样,所以说这个时候就不适用 HOC 了
而 Render Props 则是 数据给你,其他的你自己来 import React from ‘react‘; class AddNameProp extends React.Component { render() { const name = ‘cnyballk‘; return this.props.children(name); } } export default AddNameProp; 简单的使用 <AddNameProp>{name => <div>我叫 {name}</div>}</AddNameProp> 想传递给组件 <AddNameProp> {name => <Hello name={name}/>; } </AddNameProp> 或者是其他的 prop 名 <AddNameProp> {name => <Hello myName={name}/>; } </AddNameProp> 我们可以看到,这个方式很灵活,因为子组件是一个函数,一切皆有可能,所以现在有很多 Render Props 党,但是 Render Props 也有缺点就是难以做性能优化,高阶组件可以利用 SCU 来避免重复渲染。虽然这样, Render Props 却是一个非常好的一个模式,我也非常喜欢 程序员可以懒,但不能是复制粘贴的懒固然有很多人喜欢偷懒复制粘贴,但俗话说的好,复制粘贴一时爽,代码重构火葬场,一旦需要修改需求或者出现 bug,到处改显然是不行的,我们应该做好封装 小结本文介绍了 React 的高级组件的两个方式,各有优缺点,但它们都是为了重用代码,我们可以自己选择喜欢的模式去做 高阶组件代理模式可以更好的控制和实现,继承模式则可以控制特定组件的生命周期,与高阶组件相比, Render Props 模式更加灵活,有函数,我们可以更自由 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |