扩展React.js组件

Ahr*_*got 67 javascript inheritance backbone.js reactjs

我最欣赏Backbone.js的一件事是简单优雅的继承是如何工作的.我开始接触React了,并且无法找到类似于Backbone代码的任何反应

var Vehicle = Backbone.View.extend({
    methodA: function() { // ... }
    methodB: function() { // ... }
    methodC: function() { // ... }
});

var Airplane = Vehicle.extend({
    methodC: function() {
        // Overwrite methodC from super
    }
});
Run Code Online (Sandbox Code Playgroud)

在反应中我们有mixins,并且使用那些我们可以得到一些接近上面的例子,如果我们这样做

var vehicleMethods = {
    methodA: function() { // ... }
    methodB: function() { // ... }
}

var Vehicle = React.createClass({
    mixins: [vehicleMethods]
    methodC: function() { 
        // Define method C for vehicle
    }
});

var Airplane = React.createClass({
    mixins: [vehicleMethods]
    methodC: function() {
        // Define method C again for airplane
    }
});
Run Code Online (Sandbox Code Playgroud)

这比重复定义相同的东西重复性要小,但它似乎没有Backbone方式那么灵活.例如,如果我尝试重新定义/覆盖我的一个mixin中存在的方法,则会出错.最重要的是,React.js方式是我编写的更多代码.

有一些令人难以置信的聪明的东西反应,感觉就像我没有得到如何正确做到这一点,而不是感觉像React缺少一个功能.

任何指针都非常感谢.

Ros*_*len 59

为了获得类似于继承的东西(实际上是注释中指出的组合),你可以Airplane在你的例子中将一个包装在一个Vehicle.如果要VehicleAirplane组件中公开方法,可以使用ref并逐个连接它们.这不完全是继承(它实际上是组合),特别是因为this.refs.vehicle在组件安装之后才能访问它.

var Vehicle = React.createClass({
    ...
});

var Airplane = React.createClass({
    methodA: function() {
      if (this.refs != null) return this.refs.vehicle.methodA();
    },
    ...
    render: function() {
        return (
            <Vehicle ref="vehicle">
                <h1>J/K I'm an airplane</h1>
            </Vehicle>
        );
    }
});
Run Code Online (Sandbox Code Playgroud)

另外值得一提的是,在React官方文档中,他们更喜欢组合而不是继承:

那么继承怎么样?在Facebook,我们在数千个组件中使用React,并且我们没有找到任何建议创建组件继承层次结构的用例.

道具和组合为您提供了以明确和安全的方式自定义组件外观和行为所需的所有灵活性.请记住,组件可以接受任意道具,包括原始值,React元素或函数.

如果要在组件之间重用非UI功能,我们建议将其提取到单独的JavaScript模块中.组件可以导入它并使用该函数,对象或类,而无需扩展它.

另外值得一提的是,使用ES2015/ES6 +还可以将对象道具从Airplane组件传播到Vehicle组件

render: function() {
    return (
        <Vehicle {...this.props}>
            <h1>J/K I'm an airplane</h1>
        </Vehicle>
    );
}
Run Code Online (Sandbox Code Playgroud)

  • 像你这里一样,作文通常是我们建议的方法.我要补充一点,当你这样做时,你甚至可能不需要你认为可能需要的方法,并且可以通过道具和重新渲染来进行更多沟通. (13认同)

Ash*_*hot 5

如果使用项目中设置的webpack + babel + react NPM软件包,则在ES6 OOP实施中,它应该像这样简单:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

class BaseComponentClass extends Component {
  componentDidMount() {} 
  render() { return (<div>Base Component</div>) }
}
class InheritedComponentClass extends BaseComponentClass {
  // componentDidMount is inherited
  render() { return (<div>Inherited Component</div>) } // render is overridden 
}
ReactDOM.render(<InheritedComponentClass></InheritedComponentClass>, 
     document.getElementById('InheritedComponentClassHolder'));
Run Code Online (Sandbox Code Playgroud)

注意:这是一个简单的入门工具包,其设置如下:https : //github.com/alicoding/react-webpack-babel

  • 小心点。由于React建议使用合成而不是继承,因此您可能会遇到问题。我这样做了,我不得不在项目中期恢复这种方法。不好玩 (3认同)
  • @Pier非常有趣,而且[可以肯定,React文档完全说明了这一点](https://facebook.github.io/react/docs/composition-vs-inheritance.html):“ *在Facebook上,我们将React用于数以千计的组件,我们还没有找到建议创建组件继承层次结构的用例... **如果要在组件之间重用非UI功能,建议将其提取到单独的JavaScript模块中。**组件可以导入它并使用该函数,对象或类,而无需扩展它。*“ [emph mine]出现了“类”不兼容的心态。 (3认同)