正确的继承React组件的方法 [英] Correct way to inherit React components
问题描述
我明白我的问题有点偏颇,但我是Javascript和原型
的新手,我读到了它,但我真的不明白如何将这些技术应用到我的实际问题中。所以一个例子会非常有用。
所以我有一个 React
组件,基本上看起来像这样:
I understand that my question is a little bit biased, but I am very new in Javascript and prototypes
, and I read about it, but I don't really understand how to apply that techniques to my practical problems. So an example would be very helpful.
So I have a React
component, that basically looks like that:
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 />
渲染
I also have Component2
which is basically absolutely the same, but has one additional <input/>
inside the return
of its render
function.
我还有 Component3
,它共享相同的功能,但是不同的 render()
函数。
I also have Component3
, which shares same functions, but has different render()
function.
那么如何在这里应用继承并避免复制粘贴3次?我只是想念一些实用的插图,所以我很感激。
So how to apply inheritance here and avoid copy-paste 3 times? I just miss some practical illustration, so I'd appreciate it.
Edit1 ____________________________________________________
所以我尝试按照第一个答案实现Prototype继承,但似乎React没有看到这些函数: getInitialState()
为null,渲染后初始状态为null。这种方法有什么问题?
Edit1____________________________________________________
So I tried to implement Prototype inheritance as per the first answer, but it seems React doesn't see these functions: getInitialState()
is null, initial state is null after rendering. What's wrong with this approach?
我也试着按照教科书去做,并且做了:
I also tried to go according to the textbook and did:
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());
但是当我打开浏览器时,出现错误:未捕获的不变违规:createClass(...):类规范必须实现
render 方法。
But when I open my browser, I get an error: Uncaught Invariant Violation: createClass(...): Class specification must implement a
rendermethod.
我这样做错了什么?
Edit2 _______________________________________________
Edit2_______________________________________________
实际上,我看到React不支持mixins既不是原型。应该使用组合物。本文对此进行了解释:
Dan Abramov的文章Mixins Are Dead。长期合成
Actually, I see that React doesn't support mixins neither prototypes. Composition should be used instead. It's explained in this article: Dan Abramov's article Mixins Are Dead. Long Live Composition
推荐答案
在React中,组件的继承严重不鼓励。< br>
React更适合通过合成表达相同的关系。
In React, inheritance for components is severely discouraged.
React is much better suited for expressing the same relationships via composition.
以下是使用合成的示例:
Here is an example of using composition:
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
通过 props
和 DeleteButton
提供那些道具。在实际的DOM中,< Button />
和< DeleteButton />
都会呈现为单个DOM节点 - 递归解析发生在 render()
时间,这是React的核心思想。
Note how DeleteButton
uses the look and feel of Button
without inheriting from it. Instead, Button
defines its configurable parts via props
, and DeleteButton
supplies those props. In the actual DOM, both <Button />
and <DeleteButton />
would render to a single DOM node—the recursive resolution happens at the render()
time, and this is the core idea of React.
实际上,如果您不需要生命周期挂钩或本地状态,您甚至可以将组件定义为函数:
In fact, if you don’t need lifecycle hooks or local state, you may even define components as functions:
function Button({ color, children }) {
return (
<div className='Button' style={{ color }}>
{children}
</div>
)
}
function DeleteButton() {
return (
<Button color='red'>Delete</Button>
)
}
您甚至可以将类与函数混合。这对于继承来说是不可能的,但在组合方面效果很好。
You can even mix classes with functions. This would be impossible with inheritance, but works great with composition.
至于你的具体用例:
我还有
Component2
这基本上完全相同,但还有一个< input />
返回其渲染函数。
I also have
Component2
which is basically absolutely the same, but has one additional<input/>
inside the return of its render function.
你可以拥有 Component1
接受 this.props.children
并在 render()
方法的返回值中使用它们,并且 Component2
呈现为< Component1>< input />< / Component>
。这与我上面展示的非常相似。您也不必使用 children
prop - 您可以在任何道具中传递React元素,例如< Component1 footer = {< input />} />
,然后您可以使用 this.props.footer
inside Component1
。
You can have your Component1
accept this.props.children
and use them in the return value of render()
method, and have Component2
render to <Component1><input /></Component>
. This is very similar to what I showed above. You also don’t have to use the children
prop—you can pass a React element in any prop, e.g. <Component1 footer={<input />} />
, and then you can use this.props.footer
inside Component1
.
我还有
Component3
,它具有相同的功能,但具有不同的render()函数。
I also have
Component3
, which shares same functions, but has different render() function.
如果他们共享任何其他功能代码(例如计算某些数据的实用程序),将组件外部的代码移动到共享模块中,然后从两个组件中导入它。
If they share any other code (e.g. utilities that calculate some data), move that code outside components into a shared module, and import it from both components.
如果它们共享任何UI,请将其解压缩到另一个组件,并从你的组件中使用它。
If they share any UI, extract it into yet another component, and use it from both your components.
这篇关于正确的继承React组件的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!