当前位置: 首页 > 科技观察

面试官:说说你对高阶组件的理解?应用场景?

时间:2023-03-20 18:23:17 科技观察

本文转载自微信公众号《JS每日一问》,作者灰灰。转载本文请联系JS每日一问公众号。1、什么是高阶函数?至少满足以下条件之一的函数接受一个或多个函数作为输入并输出一个函数。在React中,高阶组件接受一个或多个组件作为参数并返回一个组件本质上是一个函数,而不是一个组件。constEnhancedComponent=highOrderComponent(WrappedComponent);上述代码中,函数接受一个组件WrappedComponent作为参数,返回一个处理后的新组件EnhancedComponent。这种高阶组件的实现本质上就是上面的一个装饰器设计模式2.最基本的高阶组件怎么写写模板如下:importReact,{Component}from'react';exportdefault(WrappedComponent)=>{returnclassEnhancedComponenttextendsComponent{//dosomethingrender(){return;}}}通过对传入的原始组件WrappedComponent做一些你想要的操作(比如操作props,提取state,为原始组件包裹其他元素等)),将期望的组件EnhancedComponent进行处理,将通用逻辑放在一个高层组件中,对组件进行一致的处理,从而实现代码复用。因此,一个高层组件的主要作用就是对组件的通用逻辑进行封装和分离,使得通用逻辑能够在组件之间更好的复用。在使用高阶组件时,一般会遵循一些约定,如下:保持props一致函数式(无状态)组件不能使用ref属性,因为它没有实例。不要以任何方式更改原始组件。WrappedComponent通过不相关的props属性传递给被包裹的组件WrappedComponent不要在render()方法中使用高阶组件使用compose将高阶组件包裹起来显示名称以便于调试这里需要注意的是高阶组件可以可以传递所有的props,但是不能传递refif如果给一个高层组件添加一个ref引用,那么这个ref指向的是最外层的容器组件实例,而不是被包裹的组件。如果你需要传递refs,使用React.forwardRef,如下:,...rest}=this.props;//将forwardedRef赋值给return;}};//React.forwardRef方法会传入props和ref参数给它的回调函数//所以这里的ref是由React.forwardRef函数提供的forwardRef(props,ref){return}returnReact.forwardRef(forwardRef);}constEnhancedComponent=withLogging(SomeComponent);3.应用场景通过以上理解,高阶组件可以提高代码的复用性和灵活性。在实际应用中,它们往往用在与核心业务功能无关的多个模块中,如权限控制、日志记录、数据校验、异常处理、统计报表等。比如有一个组件需要获取从缓存中获取数据然后渲染一般来说,我们会这样写:importReact,{Component}from'react'classMyComponenttextendsComponent{componentWillMount(){letdata=localStorage.getItem('data');this.setState({data});}render(){return

{this.state.data}
}}上面的代码当然可以实现这个功能,但是如果还有其他类似功能的组件,每个组件都需要重复componentWillMount中的代码,显然是下面的可以用高价组件重写,如下:);}render(){//继续将传递给当前组件的属性通过{...this.props}WrappedComponentreturn}}}classMyComponent2extendsComponent{render(){return
{this.props.data}
}}constMyComponentWithPersistentData=withPersistentData(MyComponent2)再比如组件渲染性能监控,如下:onent{constructor(props){super(props);this.start=0;this.end=0;}componentWillMount(){super.componentWillMount&&super.componentWillMount();this.start=Date.now();}componentDidMount(){super.componentDidMount&&super.componentDidMount();this.end=Date.now();console.log(`${WrappedComponent.name}组件刷新时间为${this.end-this.start}ms`);}render(){returnsuper.render();}};}exportdefaultwithTiming(Home);参考文献https://zh-hans.reactjs.org/docs/higher-order-components.html#gatsby-focus-wrapperhttps:///zh.wikipedia.org/wiki/%E9%AB%98%E9%98%B6%E5%87%BD%E6%95%B0https://segmentfault.com/a/1190000010307650https://zhuanlan.zhihu。com/p/61711492