【问题标题】:React Higher Order Components: Proper way to add instance methodsReact 高阶组件:添加实例方法的正确方法
【发布时间】:2019-08-20 11:15:06
【问题描述】:

我正在尝试将实例方法添加到包装的组件中。我通过扩展包装组件的原型来做到这一点:

const useAppContext = () => WrappedComponent => {
    WrappedComponent.prototype.$context = { abc: 'abc' };
    return class extends React.Component {
        render() {
            return <WrappedComponent {...this.props} />;
        }
    };
};

@useAppContext()
class NavigationLinkList extends Component {
    render() {
        console.log('this.$context', this.$context);
    };
};

虽然这个有效我不确定是否有更清洁的方法来做到这一点,一种是“常规”的反应方式。我在文档中找不到任何东西,这种方式似乎有点像 hack。还有其他(更清洁的?)方法吗?

【问题讨论】:

    标签: javascript reactjs higher-order-components


    【解决方案1】:

    更谨慎的方法是不修改类原型而是扩展它:

    const useAppContext = () => WrappedComponent => {
        return class extends WrappedComponent {
            $context = { abc: 'abc' };
        };
    };
    

    此时这只是一个装饰器,不是有效的高阶组件,因为它不能与函数式组件一起使用。

    React 的一种惯用方式是使用组合而不是继承。在高阶组件中扩展现有组件功能的一种常见方法是通过 props 提供必要的功能,因为 props 是 React 中组件之间通信的主要方式:

    可以是:

    const useAppContext = () => WrappedComponent => props => {
        return <WrappedComponent $context={{ abc: 'abc' }} {...props} />;
    };
    

    @useAppContext()
    class NavigationLinkList extends Component {
        render() {
            console.log(this.props.$context);
            ...
        };
    };
    

    【讨论】:

    • React 会警告 $context 不是一个有效的属性名 :)
    • @antoinechalifour 会吗? $context 不是有效的 HTML 属性,但它是有效的 prop 名称。
    【解决方案2】:

    高阶组件通常将函数添加到被包装的组件 props 中,而不是其原型中。

    向原型添加方法会使被包装的组件与装饰器耦合(这意味着它在未装饰时将无法工作)并且会使其更难测试。

    另外,提到了一个 estus,它不适用于功能组件。

    您总是可以重写您的装饰器,将上下文注入到包装的组件道具中:

    const useAppContext = () => WrappedComponent => {
        WrappedComponent.prototype.$context = { abc: 'abc' };
        return class extends React.Component {
            render() {
                return <WrappedComponent {...this.props} context={{ adb: 'abc')} />;
            }
        };
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-12
      • 1970-01-01
      • 2019-09-25
      • 2018-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-05
      相关资源
      最近更新 更多