七进七出React高阶组件
为什么要使用高阶组件?想想以前用原生和jQuery的项目,上千行的code映入眼帘,瞬间有种昏死过去的冲动。代码难以维护,改一个bug可能出现N个bug,真的是很痛苦。于是乎组件化成为了当前前端开发的主流技术。angular、vue和react很好的帮我们实现了组件化。 但是我们常常也会遇到一种情况,就是两个组件往往有很多的重复代码(可能是相同的属性,也可能是相同的方法)。例如,在登录和注册组件中,都会有用户名和密码,以及对他们的校验规则。为了提高代码的复用性和可维护性,React高阶函数应运而生。 React之前对此的解决方案是mixin,但这造成和很多不必要的问题,后来就被废弃掉了。使用过vue的同学,不知道有没有使用过mixin,react高阶函数的作用和它是一样的。 高阶组件到底是个什么东西?高阶组件其实是一个函数,它并不是一个组件,我们需要向它传递一些参数(想要操作的组件、属性)。这么说起来它其实一点也不高阶,它的作用就是存储一些公共的属性和方法。 我们经常几个人吃过一个锅底的那种火锅,锅底里有火锅底料和各种佐料,我们把肉和蔬菜等放进去涮一下,就可以美美的饱餐一顿。高阶函数在react编程中扮演的角色就是火锅锅底的角色,它有公用的方法和属性,而各种组件就是肉和蔬菜。如果是一个人一个锅的火锅就像没有经过封装的code,代码量重复且维护困难。 如何实现高阶函数?我们先来看一段可以使用高阶函数的代码:
export class Second extends React.Component { constructor(props) { super(props); this.state = { username: '' } } componentWillMount() { let username = localStorage.getItem('username'); this.setState({ username: username }); } render() { return( <div> <legend>Second Page</legend> <h2>Hi {this.state.username}</h2> </div> ) } }
export class Third extends React.Component { constructor(props) { super(props); this.state = { username: '' } } componentWillMount() { let username = localStorage.getItem('username'); this.setState({ username: username }); } render() { return( <div> <legend>Third Page</legend> <h2>Hi {this.state.username}</h2> <p>我今年18岁了</p> </div> ) } } 我们看到这两个组件除了名称以外,其余大量的代码是一样的,我们完全可以考虑将它们通用的代码提取出来。下面就是高阶组件出场的时候了。 高阶组件可以写成这样 export const HighOrderComponent = (WrapComponent,title) => { return class HOC extends React.Component { constructor(props) { super(props); this.state = { username: '' } } componentWillMount() { let username = localStorage.getItem('username'); this.setState({ username: username }); } static displayName = `HOC(${getDisplayName(WrapComponent)})`; render() { return( <div> <legend>{title}</legend> <WrapComponent username={this.state.username}></WrapComponent> </div> ) } } }
使用高阶组件之后我们要对Second和Third组件进行修改,修改如下 class Second extends React.Component { render() { return( <div> <h2>Hi {this.props.username}</h2> <h3>晓不晓得哪里好耍</h3> </div> ) } } export const HighOrderSecond = HighOrderComponent(Second,'Second Page'); class Third extends React.Component { render() { return( <div> <h2>Hi {this.props.username}</h2> </div> ) } } export const HighOrderThird = HighOrderComponent(Third,'Third Page'); 很多同学可能会问,export出去的常量是干什么用的,它就是高阶组件对组件进行封装之后的一个全新的组件,是两者的结合。到此,我们在其它页面引用组件就不再是引用Second和Third组件了,要引用的就是HighOrderSecond和HighOrderThird了。 细心的同学可能会发现一些不同的地方,对于Second和Third的公共legend提取出去了,但并没有将h2对应得标题提取出去,这里只是想给大家说一下,在对组件使用高阶组件包裹之后,高阶组件就变成了组件的父组件,它的state可以通过props的方式向子组件传递,username就是这样。我们在chrome的react插件中可以观察到这一点 今天给大家简单的介绍了React高阶组件的一些知识,后续还会再深入的挖掘React高阶组件的知识和大家分享,希望对大家有帮助。文章转自个人掘金账号,转载请注明出处,谢谢 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- MySQL到PHP到XCode?
- 一个封装好的CSV文件操作C#类代码
- 设计模式——依赖倒置原则
- Unity's Rendering Pipeline
- Flex 数组(Array)属性使用及数组的遍历
- oracle10g 如何解决 ORA-28595:Extproc 代理:DLL 路径无效
- ruby-on-rails – 如何从Mac OS X Snow Leopard上的Ruby on
- objective-c – 如何知道对象地址是否为0x0?
- 除非另外还指定了 TOP 或 FOR XML,否则,ORDER BY 子句在视
- c# – Windows.Forms Application.Run()中的无法执行的异常