简体   繁体   English

React类方法覆盖

[英]React class methods overriding

I am trying to create some kind of class composition in react: 我试图在反应中创造某种类作品:

class Entity {
  constructor(props) {
    super(props);
  }
  renderPartial() {
    return (<div>Entity</div>)
  }
  render() {
    return (<div>header {this.renderPartial()}</div>);
  }
}

class Person extends Entity{
  constructor(props) {
    super(props);
  }
  renderPartial() {
    return (<div>Person</div>)
  }
}

class Manager extends Person {
  constructor(props) {
    super(props);
  }

  renderPartial() {
    return (<div>Manager</div>)
  }
}

In the following example Person extends from Entity class. 在以下示例中, PersonEntity类扩展。 And the goal here is to render partial content inside of the extended class. 这里的目标是在扩展类中呈现部分内容。 So for the simplicity sake I just render class name. 所以为了简单起见,我只渲染类名。 This way everything works fine with Person class and it renders its text. 这样一切都可以正常使用Person类,并呈现它的文本。 But when I extend Manager from Person it writes <div>Person</div> and I can't understand why. 但是当我从Person扩展Manager时,它会写<div>Person</div>而我无法理解为什么。 Is there any way to override renderPartial inside of the Manager class? 有没有办法在Manager类中覆盖renderPartial

Don't use inheritance in React (other than extending React.Component ). 不要在React中使用继承(除了扩展React.Component )。 It's not the recommended approach. 这不是推荐的方法。 More on this here . 更多关于这里 (See also here .) (另见这里 。)

If you need outer and inner components, you can use this.props.children . 如果需要外部和内部组件,可以使用this.props.children eg 例如

render() {
  return <div>header {this.props.children}</div>;
}

This allows you to do the following: 这允许您执行以下操作:

<Entity>
  <Person />
</Entity>

But usually even this is unnecessary. 但通常即使这是不必要的。 Simply split your components into smaller pieces. 只需将组件拆分成小块即可。 eg 例如

<div>
  <Header />
  <Person />
</div>

Small, modular components are much easier to manage than gargantuan objects with long inheritance chains. 与具有长继承链的庞大对象相比,小型模块化组件更易于管理。

There is a problem with your code posted above: super() should only be used in a derived constructor. 上面发布的代码存在问题: super()只应在派生构造函数中使用。 Since Entity doesn't extend any class, super() doesn't make any sense in this context, and throws a syntax error using ES6 transpiled with babel. 由于Entity不扩展任何类,因此super()在此上下文中没有任何意义,并且使用与babel一起编译的ES6会引发语法错误。

Rendering your code in a browser will also produce a warning: "React component classes must extend React.Component" - your classes should extend React.Component , as below. 在浏览器中呈现代码也会产生警告:“React组件类必须扩展React.Component” - 您的类应该扩展React.Component ,如下所示。

As mentioned below, inheritance is not the recommended or 'React' way to share code between components ( composition is the way forward ). 如下所述,继承不是推荐的或“React”方式在组件之间共享代码( 组合是前进的方式 )。 For something as simple as your example, you would probably want to use a single component multiple times with different props: 对于像您的示例一样简单的事情,您可能希望使用不同的道具多次使用单个组件:

class Entity extends React.Component {
  render() {
    <div>header {this.props.headerType}</div>
  }
}

Entity.defaultProps = {
  headerType: 'Entity'
}

<Entity /> // renders <div>header Entity</div>
<Entity entityType ='Person' /> // renders <div>header Person</div>
<Entity entityType ='Manager' /> // renders <div>header Manager</div>

If you want to retain your named components, you can simply wrap the <Header> component and set the prop: 如果要保留命名组件,可以简单地包装<Header>组件并设置prop:

class Person extends React.Component {
  render() {
    <Entity entityType='Person' />
  }
}

<Entity /> // renders <div>header Entity</div>

However, for more complex code reuse, you might want to explore higher order components - essentially functions that wrap and return components. 但是,对于更复杂的代码重用,您可能希望探索更高阶的组件 - 实质上是包装和返回组件的函数。

let entityComponent = function(Component) {

  class EntityComponent extends React.Component {

    render() {
      return (
        <div>
          header <Component {...this.props} />
        </div>
      );
    }

  }

  EntityComponent.defaultProps = {
    headerType: 'Entity'
  }

  return EntityComponent;

}

class Entity extends React.Component {

  render() {
    return (
      <span>{this.props.headerType}</span>
    );
  }

}

Entity = entityComponent(Entity);

<Entity /> // renders <div>header <span>Entity</span></div>

class Person extends React.Component {

  render() {
    return (
      <span>{this.props.headerType}</span>
    );
  }

}

Person = entityComponent(Person);

<Person headerType='Person' /> // renders <div>header <span>Person</span></div>

A combination of these techniques should enable you to achieve what you want! 这些技术的组合应该使您能够实现您想要的!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM