【问题标题】:Which ReactJS syntax to use; React.createClass or ES6 extends?使用哪种 ReactJS 语法; React.createClass 或 ES6 扩展?
【发布时间】:2023-03-06 01:30:01
【问题描述】:

我是 ReactJS 的初学者。我在各种网站上学习和研究了很多文档和电子书。我意识到 ReactJS 有两种语法。示例:

React.createClass({
  displayName: 'Counter',
  getDefaultProps: function(){
    return {initialCount: 0};
  },
  getInitialState: function() {
    return {count: this.props.initialCount} 
  },
  propTypes: {initialCount: React.PropTypes.number},
  tick() {
    this.setState({count: this.state.count + 1});
  },
  render() {
    return (
      <div onClick={this.tick}>
        Clicks: {this.state.count}
      </div>
    );
  }
});

而且这个版本是用ES6写的:

class Counter extends React.Component {
  static propTypes = {initialCount: React.PropTypes.number};
  static defaultProps = {initialCount: 0};

  constructor(props) {
    super(props);
    this.state = {count: props.initialCount};
  }

  state = {count: this.props.initialCount};
  tick() {
    this.setState({count: this.state.count + 1});
  }

  render() {
    return (
      <div onClick={this.tick.bind(this)}>
        Clicks: {this.state.count}
      </div>
    );
  }
}

使用 ReactJS 的更好方法是什么?但是我发现这些库,github上的应用程序用于执行很多ES6。

【问题讨论】:

  • 当你有机会时,你可以将标题设置为“React.createClass vs. React.Component”我认为这会很好@PhamMinhTan

标签: syntax reactjs ecmascript-6 react-jsx


【解决方案1】:

第二种方法可能是未来采用的正确方法,因为 Facebook 已经表示他们最终会弃用 React.createClass 方法。

来自React v0.13 release notes

我们的最终目标是让 ES6 类完全取代 React.createClass,但在我们取代当前的 mixin 用例并支持该语言中的类属性初始化器之前,我们不打算弃用 React.createClass

我个人认为第二种方法也更容易阅读代码,但这显然是一个更主观的原因。

但是,如上所述,重要的是要注意 ES6 格式不支持 Mixin,因此如果您需要 mixin,则需要为该组件使用 createClass 格式。

This post "React.createClass versus extends React.Component" by Todd Motto 有一些关于这两种语法之间差异的好信息。值得一读,以讨论 this 关键字在两种语法之间的行为方式有何不同。

编辑:Dan Caragea's post below 提出了一些绝对应该考虑的优秀观点。

第三种选择...

还有第三种定义 React 组件的方法,称为“无状态函数”in the React Documentation,通常称为“无状态功能组件”或“功能无状态组件”。这是文档中的示例:

function HelloMessage(props) {
  return <div>Hello {props.name}</div>;
}

将组件定义为函数意味着它每次都有效地重新创建,因此没有持续的内部状态。这使得组件更容易推理和测试,因为组件的行为对于给定的一组属性(props)总是相同的,而不是由于内部状态的值而可能在运行之间发生变化。

这种方法在使用单独的状态管理方法(如 Redux)时特别有效,并确保 Redux 的时间旅行将产生一致的结果。功能性无状态组件还使撤消/重做等功能的实现更简单。

【讨论】:

  • 感谢@tom 提供您的信息和您的主观原因。以前,我喜欢 JSX 语法来编写我的 ReactJS 项目。但是现在,我应该重新考虑决定用 ES6 语法编写 ReactJS。 :) 谢谢
  • 我喜欢用的是复合方式,React.createClass。 ES6 类只是糖,对使用工厂创建没有任何实际价值(至少对我而言)。也许装饰器会在 ES6 类中派上用场,但这可以通过使用高阶函数来轻松实现。所以我的赌注是 ES6 + React.createClass === win
【解决方案2】:

我已经为我的宠物项目完成了工作和 ES6 课程的 React.createClass。我确实发现后者也更容易阅读,但我经常怀念前者的简单/安心。 使用基于类的方法,请注意,从技术上讲,静态定义的 propTypes 和 defaultProps 是 ES7,而不是 ES6——在 ES7 最终确定之前可能会发生变化。 纯粹的 ES6 方法是声明 propTypes/defaultProps 之类的

class Counter extends React.Component {
...
}
Counter.propTypes = {...};
Counter.defaultProps = {...};

您还必须记住在渲染中绑定 onClick(或您需要使用this 的任何其他方法)。几乎可以肯定你会在某些地方忘记。使用 createClass 时,所有调用都由 React 自动绑定。 另一个 ES7 提案可以使事情变得更容易,但你仍然需要记住在任何地方都写它: &lt;div onClick={::this.tick}&gt;this 绑定到 tick。 当然,您必须在 babel 配置中选择进入第 0 阶段才能使用所有这些 ES7 提议。

关于 mixins...有一些可以接受的方式将 mixin 与类一起使用。 mixWith.js 是一个绝妙的方法,但您也可以尝试 ES7 装饰器、HOC,甚至 Object.assign() :)

归根结底,我觉得 class 方法并没有带来任何真正的价值,在你对 React 有很好的理解之前,你可以使用 createClass 的老方法。然后你可以玩转类和 ES6/7/100。他们还需要很长时间才能弃用 createClass

【讨论】:

    【解决方案3】:

    我从 React ES6 + staging 风格开始,当你在 React 中说一切都是组件时听起来不错。我喜欢这个class 组织。

    因为只有方法可以在 ES6 class 中定义,如果你想在纯 ES6 中定义属性,它们必须在类之外。比如这里:

    export class Counter extends React.Component {
      constructor(props) {
        super(props);
        this.state = {count: props.initialCount};
      }
      tick() {
        this.setState({count: this.state.count + 1});
      }
      render() {
        return (
          <div onClick={this.tick.bind(this)}>
            Clicks: {this.state.count}
          </div>
        );
      }
    }
    Counter.propTypes = { initialCount: React.PropTypes.number };
    Counter.defaultProps = { initialCount: 0 };
    

    这就是为什么在 ES6 中 propTypes 部分在类定义之外。

    但是,如果您使用 ES7,您可以在 class 内部定义静态和非静态属性而不会出现问题。

    // ES7
    export class Counter extends React.Component {
      static propTypes = { initialCount: React.PropTypes.number };
      static defaultProps = { initialCount: 0 };
      state = { count: this.props.initialCount };
      tick() {
        this.setState({ count: this.state.count + 1 });
      }
      render() {
        return (
          <div onClick={this.tick.bind(this)}>
            Clicks: {this.state.count}
          </div>
        );
      }
    }
    

    在 ES7 中,您可以对方法使用隐式绑定提示,如 here 所示:

    return (
          <button onClick={(e) => this.handleClick(e)}>
            Click me
          </button>
    );
    

    旧的 pre React v0.13 样式或 ES5 样式是这样的。

    React.createClass中,所有方法都自动绑定了这个。

    这对于 JavaScript 开发人员来说可能有点混乱,因为这不是原生 JavaScript 行为。

    这是写的:

    class Counter extends React.Component {
      constructor() {
        super();
        this.tick = this.tick.bind(this);
      }
      tick() {
        ...
      }
      ...
    }
    

    或者使用一些技巧来使用属性初始化语法来完成同样的事情。

    class Counter extends React.Component {
      tick = () => {
        ...
      }
      ...
    }
    

    结束

    对于新人来说,我觉得最新款是更好的选择。


    关于 Mixins

    here所述:

    ES6 在没有任何 mixin 支持的情况下启动。因此,当您将 React 与 ES6 类一起使用时,不支持 mixins。 我们还在使用 mixin 的代码库中发现了许多问题,并且不建议在新代码中使用它们。 此部分仅供参考。

    【讨论】:

      猜你喜欢
      • 2016-07-15
      • 1970-01-01
      • 2017-12-24
      • 2020-02-24
      • 1970-01-01
      • 2017-04-03
      • 2021-03-04
      相关资源
      最近更新 更多