我最欣赏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
}
});
在做出反应我们have 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
}
});
这比重复定义相同内容的重复性要小,但它似乎没有Backbone方式那么灵活。例如,如果我尝试重新定义/覆盖我的一个mixin中存在的方法,则会出错。最重要的是,React.js方式是我编写的更多代码。
有一些令人难以置信的聪明的东西反应,感觉就像我没有得到如何正确地做到这一点,而不是感觉像React缺少一个功能。
非常感谢任何指针。
答案 0 :(得分:59)
要获得类似于继承的内容(实际上 composition ,如注释中所指出的那样),您可以在示例中将Airplane
包裹在Vehicle
中。如果您想在Vehicle
组件的Airplane
上公开方法,可以使用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>
);
}
});
另外值得一提的是,React official documentation他们更喜欢构图而不是继承:
那么继承怎么样?在Facebook,我们使用React成千上万 组件,我们还没有找到任何用例 建议创建组件继承层次结构。
道具和作曲为您提供所需的所有灵活性 以明确和安全的方式定制组件的外观和行为。 请记住,组件可以接受任意道具,包括 原始值,React元素或函数。
如果您想在组件之间重用非UI功能,我们 建议将其解压缩到一个单独的JavaScript模块中。该 组件可以导入它并使用该函数,对象或类, 没有扩展它。
另外值得一提的是,使用ES2015 / ES6 +还可以将对象道具从Airplane
组件传播到Vehicle
组件
render: function() {
return (
<Vehicle {...this.props}>
<h1>J/K I'm an airplane</h1>
</Vehicle>
);
}
答案 1 :(得分:4)
如果您在项目中使用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'));
注意:这是一个简单的入门套件,具有这样的设置:https://github.com/alicoding/react-webpack-babel
答案 2 :(得分:3)
通过利用ReactOO,您可以轻松使用继承(免责声明:我是 ReactOO 的作者):
(function () {
// Class definitions. ReactOO requires class definition first just like you did in an OO way.
window.Vehicle = window.ReactOO.ReactBase.extend({
getReactDisplayName: function () {
return 'Vehicle';
},
onReactRender: function (reactInstance) {
var self = this;
var text = self.methodC();
return React.createElement('div', {}, text);
},
methodA: function () {
console.log('Vehicle method A');
},
methodB: function () {
console.log('Vehicle method B');
},
methodC: function () {
return 'Vehicle method C';
}
});
window.Airplane = window.Vehicle.extend({
getReactDisplayName: function () {
return 'Airplane';
},
methodC: function () {
// Call this._super() to execute parent method.
//this._super();
return 'Airplane method C';
}
});
var vehicle = new window.Vehicle();
vehicle.render({}, '#vehicle');
var airPlane = new window.Airplane();
airPlane.render({}, '#airPlane');
})();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>ReactOO Vehicle-Aireplane Example</title>
<link rel="stylesheet" href="css/base.css" />
<script src="scripts/react.js"></script>
<script src="scripts/react-dom.js"></script>
<script src="../src/reactoo.js"></script>
</head>
<body>
<div id="vehicle">
</div>
<div id="airPlane">
</div>
<script src="scripts/vehicleAirplane.js">
</script>
</body>
</html>
答案 3 :(得分:-4)
我认为可以使用jQuery.extend
或类似的
<强> Base.jsx 强>
module.exports = {
methodA:function(){
...
}
}
<强> Child.jsx 强>
var Base = require('./Base.jsx');
module.exports = React.createClass($.extend({},Base,{
methodB:function(){
...
this.methodA();
...
},
render:function(){
return ...
}
}));