【问题标题】:React class methods overridingReact 类方法覆盖
【发布时间】:2016-01-26 00:56:07
【问题描述】:

我正在尝试在 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>)
  }
}

在以下示例中,Person 扩展自 Entity 类。这里的目标是在扩展类中呈现部分内容。所以为了简单起见,我只渲染类名。这样,Person 类的一切都可以正常工作并呈现其文本。但是当我从 Person 扩展 Manager 时,它会写 &lt;div&gt;Person&lt;/div&gt; 我不明白为什么。有没有办法在Manager 类中覆盖renderPartial?

【问题讨论】:

标签: javascript reactjs ecmascript-6


【解决方案1】:

不要在 React 中使用继承(除了扩展 React.Component)。这不是推荐的方法。更多关于这个here。 (另见here。)

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

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

这允许您执行以下操作:

<Entity>
  <Person />
</Entity>

但通常即使这样也是不必要的。只需将您的组件拆分成更小的部分。例如

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

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

【讨论】:

    【解决方案2】:

    上面发布的代码存在问题:super() 只能在派生构造函数中使用。由于Entity 没有扩展任何类,super() 在这种情况下没有任何意义,并且使用 ES6 转译 babel 会引发语法错误。

    在浏览器中呈现您的代码也会产生警告:“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>
    

    如果你想保留你的命名组件,你可以简单地包装&lt;Header&gt; 组件并设置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>
    

    这些技术的组合应该可以让你实现你想要的!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-08
      • 2021-12-25
      • 1970-01-01
      • 2022-12-04
      • 2021-07-09
      • 2011-04-17
      • 2012-11-20
      相关资源
      最近更新 更多