React ES6 类中的实例属性

IT技术 javascript reactjs es6-class
2021-05-04 06:15:52

如何在 React 中定义状态,如下所示:

class Test extends React.Component {
  state = { foo: 'bar' }
}

但是为了定义其他实例属性,您需要在构造函数或其他函数中进行吗?就像,你不能这样做:

 class Test extends React.Component {
  myField = 0;

  render() {
    myField++
  }
}
4个回答

你可以这样做:

class Test extends React.Component {
  myField = 0;

  render() {
    this.myField++ // use this to access class properties
  }
}

但是避免使用普通的类属性并使用状态属性,就像在你的第一个例子中一样。所以,你可以:

  1. 必要时使用this.setState().
  2. 强制更新并使用 重新渲染组件this.forceUpdate()
  3. 重新渲染父组件。
  4. 从 React 的生命周期钩子更改属性,例如 shouldComponentUpdate()

  5. 不允许从范围之外改变属性,例如。如果您使用的是普通属性,那么您可以从浏览器控制台更改它。


您可能需要普通属性,例如在以下情况下:

在构造函数中将计时器设置为普通类属性

this.timer = setTimeout(..)

清除 componentWillUnmount 中的计时器

componentWillUnmount (clearTimeout(this.timer))

你可以做到this.myField++尽管语法是错误的,因为您必须从渲染中返回一些内容,例如:

class Test extends React.Component {
  myField = 0;

  render() {
    return <div>this.myField++</div>
  }
}

你不会看到1那里,因为 React 首先看到 myField 的值并渲染它。

但我认为实际问题不在于我们如何使用它。这是关于 ES 的一个新提案:类字段。这是对此的解释:https : //stackoverflow.com/a/50789811/7060441

这是 ES 的一个新提案(类字段),目前处于 [stage 3][1]。要运行以这种方式编写的代码,您需要一个像 Babel 这样的转译器和一个合适的插件。

转译前:

class A {
  static color = "red";
  counter = 0;

  handleClick = () => {
    this.counter++;
  }
}

转译后(在 Babel Repl 上使用第 2 阶段):

class A {
  constructor() {
    this.counter = 0;

    this.handleClick = () => {
      this.counter++;
    };
  }

}
A.color = "red";

另外官方的提议[2ality blog post][2] 是一个很好的来源,看看有什么细节。

这是一个 [reddit 帖子][3] 如果你有时间阅读讨论风暴这个提议背后的原因是什么:)

这里的箭头函数是另一回事。您可以在没有构造函数的情况下使用实例属性,并将您的代码与标准函数混合使用。但是当你想使用类似的东西时,this它就不起作用了:

class App extends React.Component {
  state = { bar: "baz"}

  foo() { console.log(this.state.bar) };

  render() {
    return <div><button onClick={this.foo}>Click</button></div>;
  }
}

我们需要以某种方式绑定我们的函数:

return <div><button onClick={this.foo.bind(this)}>Click</button></div>

但是,在 JSX props中绑定我们的函数并不是那么好,因为它会在每个渲染中创建我们的函数。

一种在我们的构造函数中很好地绑定的方法:

constructor(props) {
    super(props);
    this.foo = this.foo.bind( this );
  }

但是,如果我必须写一个构造函数有什么意义呢?这就是为什么在我们定义类的任何地方都会看到箭头函数,就像你的第二个例子。由于箭头函数,无需绑定到函数。但我认为它与这个新提案没有直接关系。

[1]:https : //github.com/tc39/proposal-class-fields [2]:http : //2ality.com/2017/07/class-fields.html [3]: https://www. reddit.com/r/javascript/comments/6q0rov/es_proposal_class_fields/

答案是您可以,但不能myField++将其更改为this.myField++一个例子在小吃创建@这里

它确实与 React 没有太大关系,但更多的是关于 JS 中的一般类概念。了解更多关于class的信息

这种语法就是语法糖。在这方面,JavaScript 没有什么“新的”。它抽象出创建构造函数的概念,其唯一目的是在class的上下文中声明变量,并为您完成。这些是等效的:

class Sample {
  dog = 1
}

class Sample {
  constructor() {
    this.dog = 1
  }
}