React的高阶组件怎么用()

一、高阶组件是什么? 高阶组件(HOC)是一个接收组件作为参数并返回新组件的函数。将多个组件的相同逻辑代码,抽象到HOC中,让组件更有结构化,更易于复用。HOC不破坏传入组件的特性,只通过组合形成新组件。HOC是纯函数,没有副作用。
二、高阶组件实例 接受了组件WrappedComponent,增加了订阅和数据刷新的操作。

// 此函数接收一个组件... function withSubscription(WrappedComponent, selectData) { // ...并返回另一个组件... return class extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { data: selectData(DataSource, props) }; }componentDidMount() { // ...负责订阅相关的操作... DataSource.addChangeListener(this.handleChange); }componentWillUnmount() { DataSource.removeChangeListener(this.handleChange); }handleChange() { this.setState({ data: selectData(DataSource, this.props) }); }render() { // ... 并使用新数据渲染被包装的组件! // 请注意,我们可能还会传递其他属性 return ; } }; }

想要增加订阅和数据刷新功能的组件,都可以使用withSubscription,调用如下:
const CommentListWithSubscription = withSubscription( CommentList, (DataSource) => DataSource.getComments() ); const BlogPostWithSubscription = withSubscription( BlogPost, (DataSource, props) => DataSource.getBlogPost(props.id) );

三、只组合,不破坏原组件 1、错误:已经破坏
function logProps(InputComponent) { InputComponent.prototype.componentDidUpdate = function (prevProps) { console.log('Current props: ', this.props); console.log('Previous props: ', prevProps); }; // 返回原始的 input 组件,暗示它已经被修改。 return InputComponent; }// 每次调用 logProps 时,增强组件都会有 log 输出。 const EnhancedComponent = logProps(InputComponent);

2、正确:组合组件
function logProps(WrappedComponent) { return class extends React.Component { componentDidUpdate(prevProps) { console.log('Current props: ', this.props); console.log('Previous props: ', prevProps); } render() { // 将 input 组件包装在容器中,而不对其进行修改。Good! return ; } } }

四、相似接口 HOC 返回的组件与原组件应保持类似的接口。
render() { const { extraProp, ...passThroughProps } = this.props; const injectedProp = someStateOrInstanceMethod; return ( ); }

五、HOC方便调试 用HOC包裹组件,加上HOC和组件的名字,调试时输出,方便准确定位bug位置。
function withSubscription(WrappedComponent) { class WithSubscription extends React.Component {/* ... */ } WithSubscription.displayName = `WithSubscription(${getDisplayName(WrappedComponent)})`; return WithSubscription; }function getDisplayName(WrappedComponent) { return WrappedComponent.displayName || WrappedComponent.name || 'Component'; }

六、render()中禁止使用HOC 在render方法中使用HOC,每一次HOC都会产生一个新组件,使得原来组件被卸载,再重新加载新组件,这不仅仅是性能问题 - 重新挂载组件会导致该组件及其所有子组件的状态丢失。
render() { // 每次调用 render 函数都会创建一个新的 EnhancedComponent // EnhancedComponent1 !== EnhancedComponent2 const EnhancedComponent = enhance(MyComponent); // 这将导致子树每次渲染都会进行卸载,和重新挂载的操作! return ; }

七、静态方法与HOC 用HOC包裹原组件,形成新组件,将不能访问原始组件的静态方法。
// 定义静态函数 WrappedComponent.staticMethod = function() {/*...*/} // 现在使用 HOC const EnhancedComponent = enhance(WrappedComponent); // 增强组件没有 staticMethod typeof EnhancedComponent.staticMethod === 'undefined' // true

【React的高阶组件怎么用()】可以通过下面这个方案解决:
// 使用这种方式代替... MyComponent.someFunction = someFunction; export default MyComponent; // ...单独导出该方法... export { someFunction }; // ...并在要使用的组件中,import 它们 import MyComponent, { someFunction } from './MyComponent.js';

八、参考链接:
  • React的高阶组件怎么用?

    推荐阅读