装饰器或子类化是React.Component的最佳模式

Decorators or subclassing is best pattern for React.Component

本文关键字:Component React 最佳 模式 子类      更新时间:2023-09-26

推荐哪种方式,为什么?

way_1:(使用继承)

class BaseComponent extends React.Component {
    //Other functions
    log = (msg) => {
        console.log(`[${this.constructor.name}]`, msg);
    }
    //Other functions
}
export default BaseComponent;

class XyzComponent extends BaseComponent {
    //Other functions
    someFunction = () => {
        this.log("Some log");
    }
    //Other functions
}
export default XyzComponent;

way_2:(使用装饰器)

function withLog(ComposedComponent) {
    return class withLog extends Component {
        log = (msg) => {
            console.log(`[${this.constructor.name}]`, msg);
        }
    }
};
export default withLog;
@withLog
class XyzComponent extends React.Component {
    //Other functions
    someFunction = () => {
        this.log("Some log");
    }
    //Other functions
}

我喜欢way_1,因为它看起来像其他基于OOP的语言。这使得恒定性和更容易理解。但在其他地方,人们都在谈论装饰师。所以我有点困惑。

人们可能会回收装饰器,因为他们内化了您想要的功能。

当您在第一个示例中从BaseComponent继承时,您在XyzComponentBaseComponent之间创建了一个强(继承)依赖关系。然后,对BaseComponent的任何更改都可能对XyzComponent s产生间接影响。

更可能的情况是,稍后您决定更改XyzComponent的日志记录方法。如果采用第一种方法,可能很难"去掉中间部分"并从React.Component继承,因为代码库的其他部分可能通过其BaseComponent超类访问XyzComponent。在这种情况下,您必须确保您的修改不会违反BaseComponent的合同。

因此,尽管继承方法很容易掌握,而且非常面向对象,但可能会在以后引起头痛。如果你意识到这些令人头疼的问题,请做出判断——我个人认为,当装饰师更间接时,继承是不言自明的。

(这个答案可以总结为:"比起继承,更喜欢构图")