javascript - 继承 React 组件的正确方式

标签 javascript inheritance reactjs prototype prototype-programming

我知道我的问题有点偏颇,但我是 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 次呢?我只是错过了一些实际的例子,所以我很感激。

编辑1______________________________________________________ 所以我尝试按照第一个答案实现 Prototype 继承,但似乎 React 没有看到这些功能:getInitialState()为空,渲染后初始状态为空。这种方法有什么问题?

我也试着按照课本去做:

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.

我这样做错了什么?

编辑 2___________________________________________________________

实际上,我看到 React 既不支持混合也不支持原型(prototype)。应该改用合成。它在这篇文章中解释: Dan Abramov's article Mixins Are Dead. Long Live Composition

最佳答案

在 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提供那些 Prop 。在实际的 DOM 中,<Button /> 都是和 <DeleteButton />将渲染到单个 DOM 节点——递归解析发生在 render() 处时间,这就是 React 的核心思想。

事实上,如果您不需要生命周期钩子(Hook)或本地状态,您甚至可以将组件定义为函数:

function Button({ color, children }) {
  return (
    <div className='Button' style={{ color }}>
      {children}
    </div>
  )
}

function DeleteButton() {
  return (
    <Button color='red'>Delete</Button>
  )
}

您甚至可以将类与函数混合使用。这对于继承来说是不可能的,但对于组合来说效果很好。

至于您的具体用例:

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——你可以在任何 prop 中传递一个 React 元素,例如<Component1 footer={<input />} /> , 然后你可以使用 this.props.footer里面Component1 .

I also have Component3, which shares same functions, but has different render() function.

如果他们共享任何其他代码(例如计算某些数据的实用程序),请将该代码从组件外部移到共享模块中,然后从两个组件中导入它。

如果他们共享任何 UI,请将其提取到另一个组件中,并在您的两个组件中使用它。

关于javascript - 继承 React 组件的正确方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36973459/

相关文章:

c++ - 继承基于模板的数据结构有什么好处?

node.js - 无法在 React 应用程序中导入图像 "Invalid or unexpected token"

reactjs - Ref 对象可能是未定义的 TypeScript React

javascript - 在浏览器 session 之间保持用户登录状态

javascript - 向函数内的对象添加值

java - 流畅的语法和继承

c++ - 编译器如何在继承 C++ 中进行组合?

javascript - 使用 flex box,使用父节点的 clientWidth 和 Height 设置 Canvas 的宽度和高度隐藏粘性页脚

javascript - Angular JS - 清除后文本框未更新

reactjs - React-Router的Link-To更新URL但不刷新页面