reactjs - React 中组合优于继承的好处

标签 reactjs inheritance composition

我很难在 React 中用继承代替组合。我将尝试根据 React 样式指南中不鼓励的继承来解释提出的问题和我当前的解决方案。

首先,我在一个 super 组件中定义了公共(public)状态和方法:

export default class SuperComponent extends Component {
    constructor(props) {
        super(props);
        this.state = commonState;
    }

    foo() {
        this.setState({a: 3});
    }

    render() {
        return (
            <div>
                {this.getContent()}
            </div>
        )
    }
}

然后我制作具有可能更多状态和方法的子组件。这些也应该可以访问 super 组件的状态:
export default class SubComponent1 extends SuperComponent {
    constructor(props) {
        super(props);
        this.state = Object.assign(this.state, subComponent1State);
    }

    bar() {
        this.setState({b: 7});
    }

    getContent() {
        return (
            <div>
                I'm subcomponent 1
            </div>
        )
    }
}

export default class SubComponent2 extends SuperComponent {
    constructor(props) {
        super(props);
        this.state = Object.assign(this.state, subComponent2State);
    }

    bar() {
        this.setState({c: 1});
    }

    getContent() {
        return (
            <div>
                I'm subcomponent 2
            </div>
        )
    }
}

当我尝试将其转换为基于组合的方法时,我得到了这个:
export default class SuperComponent extends Component {
    foo() {
        this.props.setStateMethod({a: 3});
    }

    render() {
        return (
            <div>
                <div>
                    {this.props.text}
                </div>
            </div>
        )
    }
}

export default class SubComponent1 extends Component {
    constructor(props) {
        super(props);
        this.state = Object.assign(commonState, subComponent1State);
    }

    bar() {
        this.setState({b: 7});
    }

    render() {
        return (
            <SuperComponent
                text={"I'm subcomponent 1"}
                setStateMethod={this.setState}
                subComponentState={this.state}
            />
        )
    }
}

export default class SubComponent2 extends Component {
    constructor(props) {
        super(props);
        this.state = Object.assign(commonState, subComponent2State);
    }

    bar() {
        this.setState({c: 1});
    }

    render() {
        return (
            <SuperComponent
                text={"I'm subcomponent 2"}
                setStateMethod={this.setState}
                subComponentState={this.state}
            />
        )
    }
}

这是将基于继承的解决方案转换为基于组合的解决方案的好方法吗?由于公共(public)状态和差异状态更好地分开,基于继承的不是更好吗?在基于组合的解决方案中,必须在初始化时在每个子组件中定义公共(public)状态。

最佳答案

首先,你应该阅读 React's Team response on the matter .

代码很模糊,所以我无法判断您的情况是否真的很特殊,但我对此表示怀疑,所以让我解决普遍共识:

在真空中,继承和组契约(Contract)样有用。在某些语言或项目中,您会更喜欢从一个公共(public)类继承,而不是导入和调用十几个函数,但在 React 中,主要是因为它是以组件为中心的方法,事实恰恰相反。

组合让 React 只做两件事:propsstate .你相信你收到的东西,以可预测的方式行事并反射(reflect)两者 propsstate在您呈现的内容中。如果您需要稍微更改渲染的内容,可以发送不同的 props ,甚至可能制作一个包装第一个用于特定用途的组件。该组件甚至可以有一些自己的逻辑,并通过 render props 向下传递。因此您可以更精确地控制结果。如果您需要使用此逻辑包装不同的组件,您可以创建 HOC并轻松包装任何组件。那时,您可以制作数十个组件,将不同的东西返回到相同的 props并且可以在组件库之间切换以显示数据并进行处理。

尽管 Render props 或 HOC 之类的东西看起来不同,但它们只是使用现有组件逻辑的技术,并以允许您重用代码并在 React 中仍然有意义的方式应用它。这是一个很好的解决方案吗?好吧,它有效,但你最终会陷入困境并杂耍二十个几乎相同的概念。这就是为什么现在有一个 proposal用于改变范式的新特性,它介于继承和组合之间。但是组合在 React 的做事方式中仍然没有多大意义。

归根结底,这只是看待同一问题的不同方式。组合与 React 一起工作得更好,并让您在 render 中获得更多控制权混合和匹配你需要的东西。

同样,如果你有一个实际的例子,我可以给你一个更好的解释,应用不同的 React 技术,但对于你目前的技术,显然没有好或坏的方法,因为它什么都不做。这需要一些时间来修补而不是解释。

关于reactjs - React 中组合优于继承的好处,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51603767/

相关文章:

ios - 未调用 Swift 类函数

java - 在 main 方法的类中扩展 Frame 类

javascript - 通过 map 获取具体结果

ajax - CORS google chrome 扩展有什么替代品吗?如何在不使用 CORS 的情况下发出成功的 ajax 请求?

javascript - React - 由于某种原因,Babel Polyfill 不会阻止 Set 或 Weakmap 上的异常,但会填充 Promise

Java - 是否可以用一个类扩展一个类的所有子类?

派生类上的 C++ 赋值运算符实现

class - 两个类之间的 OOP 关系

javascript - 将函数与 JavaScript 组合起来变得更加 'Functional'

javascript - 按相同的属性值对数组进行分组,遍历该数组