【问题标题】:Instance property in React ES6 classReact ES6 类中的实例属性
【发布时间】:2018-06-14 03:34:07
【问题描述】:

如何在 React 中定义如下状态:

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

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

 class Test extends React.Component {
  myField = 0;

  render() {
    myField++
  }
}

【问题讨论】:

    标签: javascript reactjs es6-class


    【解决方案1】:

    你可以这样做:

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

    【讨论】:

      【解决方案2】:

      你可以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 的新提案(类字段),处于 [阶段 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 属性中并不是那么好,因为它会 在每个渲染中创建我们的函数。

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

      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/

      【讨论】:

        【解决方案3】:

        答案是可以,但不要将myField++ 改为this.myField++。零食上创建的例子@here

        它实际上与 React 没有太大关系,但更多的是 JS 中的一般类概念。了解more关于课程

        【讨论】:

          【解决方案4】:

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

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

          【讨论】:

            猜你喜欢
            • 2015-12-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-19
            • 1970-01-01
            • 1970-01-01
            • 2020-03-28
            • 2011-11-24
            相关资源
            最近更新 更多