问题
React17 中对高阶组件的作用正确的是?
选项
A. 高阶组件是参数为组件,返回值为新组件的函数。
B. HOC 定义方式为修改传入的组件,或者通过继承方式进行复制。
C. 可用于渲染劫持。
D. 在 render
方法中使用 HOC 不会有性能问题。
答案
A、C
纠错
B. HOC 通过将组件包装在容器组件中来组成新组件。
C. 在 render
方法中使用 HOC 会有性能问题。
解答
高阶组件(HOC)是 React 用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。
组件是将 props 转换为 UI,而高阶组件是将组件转换为另一个组件。
const EnhancedComponent = higherOrderComponent(WrappedComponent);
不要在 render 方法中使用 HOC
如下的代码,就会导致子树每次渲染都会进行卸载,和重新挂载的操作。
render() { // 每次调用 render 函数都会创建一个新的 EnhancedComponent // EnhancedComponent1 !== EnhancedComponent2 const EnhancedComponent = enhance(MyComponent); return <EnhancedComponent />; }
这不仅仅是性能问题 - 重新挂载组件会导致该组件及其所有子组件的状态丢失。
如果在组件之外创建 HOC,这样一来组件只会创建一次。因此,每次 render 时都会是同一个组件。
静态属性需要手动复制
因为高阶返回的是一个新的组件(类),传入的组件所具有的静态属性,需要手动进行复制。否则就会出现类似下面的情况:
// 定义静态函数 WrappedComponent.staticMethod = function() {/*...*/} // 现在使用 HOC const EnhancedComponent = enhance(WrappedComponent); // 增强组件没有 staticMethod typeof EnhancedComponent.staticMethod === 'undefined' // true
除了手动复制外,还可以使用 hoist-non-react-statics 自动拷贝所有非 React 静态方法。
关于 Ref 的转发
高阶组件可以看做是一个容器组件,传入的参数组件成了子组件,而 Ref 仅能获取子组件实例且无法通过 props 获取的特性。基于此原因当对给高阶组件传 ref 属性时,拿到的是容器组件实例,而非真实的目标组件。
此时就需要使用 React.forwardRef() 提供的 ref 转发功能,实现如下:
function enhance(WrappedComponent) { class EnhancedComponent extends React.Component { render() { const {forwardedRef, ...rest} = this.props; return <WrappedComponent ref={forwardedRef} {...rest} />; } } return React.forwardRef((props, ref) => { return <EnhancedComponent {...props} forwardedRef={ref} />; }); }
资料
来源
搜索《考试竞技》微信小程序