我理解我的问题有点偏颇,但我在Javascript和prototypes
中都是新手,我读到了它,但我真的不明白如何将这些技巧应用于我的实际问题。所以一个例子会非常有用。
所以我有一个React
组件,基本上看起来像这样:
var Component1 = React.createClass({
getInitialState: function () {
return ({
searchable: true,
})
},
function1: function () {
return ({
somevalue
})
},
render: function () {
var redText = {
color: 'red'
};
var redBorder = {
color: 'red',
border: '1px solid red'
};
return (
<form>
<div>
<a onClick={this.props.handleAddClick}>Something</a>
</div>
<div>
<label>Some label</label>
<input type="text"/>
</div>
</form> )
});
我的Component2
基本上完全相同,但在其<input/>
函数的return
内还有一个render
。
我也有Component3
,它共享相同的功能,但具有不同的render()
功能。
那么如何在这里应用继承并避免复制粘贴3次?我只是想念一些实用的插图,所以我很感激。
EDIT1 ____________________________________________________
所以我尝试按照第一个答案实现Prototype继承,但似乎React没有看到这些函数:getInitialState()
为null,渲染后初始状态为null。这种方法有什么问题?
我也试着按照教科书去做,并做了:
function MyPrototype() {};
MyPrototype.prototype.getInitialState = function () {
return ({
someProperty: true;
})
};
function Component1() {};
Component1.prototype = Object.create(MyPrototype.prototype);
Component1.prototype.render = function () {
console.log(this);
return (<div></div>)};
var MyComponent1 = React.createClass(new Component1());
但是当我打开浏览器时,出现错误:Uncaught Invariant Violation: createClass(...): Class specification must implement a
呈现method.
我这样做错了什么?
EDIT2 _______________________________________________
实际上,我发现React并不支持mixins,也不支持原型。应该使用组合物。它在本文中进行了解释: Dan Abramov's article Mixins Are Dead. Long Live Composition
答案 0 :(得分:4)
在React中,组件的继承严重劝阻 React更适合通过合成来表达相同的关系。
以下是使用合成的示例:
class Button extends Component {
render() {
return (
<div className='Button' style={{ color: this.props.color }}>
{this.props.children}
</div>
)
}
}
class DeleteButton extends Component {
render() {
return (
<Button color='red'>Delete</Button>
)
}
}
请注意DeleteButton
如何在不继承的情况下使用Button
的外观。相反,Button
通过props
定义其可配置部分,DeleteButton
提供这些道具。在实际的DOM中,<Button />
和<DeleteButton />
都会呈现给单个DOM节点 - 递归解析发生在render()
时,这是React的核心思想。
实际上,如果您不需要生命周期挂钩或本地状态,您甚至可以将组件定义为函数:
function Button({ color, children }) {
return (
<div className='Button' style={{ color }}>
{children}
</div>
)
}
function DeleteButton() {
return (
<Button color='red'>Delete</Button>
)
}
您甚至可以将类与函数混合使用。继承这是不可能的,但在组合方面效果很好。
至于您的具体用例:
我也有
Component2
基本上完全相同,但在渲染函数返回时还有一个<input/>
。
您可以让Component1
接受this.props.children
并在render()
方法的返回值中使用它们,并Component2
呈现给<Component1><input /></Component>
。这与我上面展示的非常相似。您也不必使用children
道具 - 您可以在任何道具中传递React元素,例如<Component1 footer={<input />} />
,然后您可以在this.props.footer
内使用Component1
。
我也有
Component3
,它共享相同的功能,但具有不同的render()函数。
如果他们共享任何其他代码(例如计算某些数据的实用程序),请将组件外部的代码移动到共享模块中,然后从两个组件中导入。
如果他们共享任何UI,请将其提取到另一个组件中,并从两个组件中使用它。