React类方法覆盖

时间:2016-01-26 00:56:07

标签: javascript reactjs ecmascript-6

我试图在反应中创造某种类作品:

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>)
  }
}

在以下示例中,PersonEntity类扩展而来。这里的目标是在扩展类中呈现部分内容。所以为了简单起见,我只渲染类名。这样一切都可以正常使用Person类,并呈现它的文本。但是当我从Person扩展Manager时,它会写<div>Person</div>而我无法理解为什么。有没有办法覆盖renderPartial类内的Manager

2 个答案:

答案 0 :(得分:8)

不要在React中使用继承(除了扩展React.Component)。这不是推荐的方法。有关此问题的更多信息here。 (另见here。)

如果您需要外部和内部组件,可以使用this.props.children。 e.g。

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

这允许您执行以下操作:

<Entity>
  <Person />
</Entity>

但通常即使这是不必要的。只需将组件拆分成小块即可。 e.g。

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

小型模块化组件比具有长继承链的庞大对象更容易管理。

答案 1 :(得分:1)

上面发布的代码存在问题:super()只应在派生构造函数中使用。由于Entity不扩展任何类,super()在此上下文中没有任何意义,并且使用与babel描述的ES6会引发语法错误。

在浏览器中呈现代码也会产生警告:“React组件类必须扩展React.Component” - 您的类应该扩展React.Component,如下所示。

如下所述,继承不是在组件之间共享代码的推荐或“反应”方式(composition is the way forward)。对于像您的示例一样简单的事情,您可能希望使用不同的道具多次使用单个组件:

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>

如果要保留命名组件,可以简单地包装<Header>组件并设置prop:

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

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

但是,对于更复杂的代码重用,您可能希望探索更高阶的组件 - 实质上是包装和返回组件的函数。

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>

这些技术的组合应该可以让你达到你想要的效果!