无法访问“ this”的Reactjs→静态方法,还有什么选择?

时间:2018-09-15 21:58:17

标签: reactjs this static-methods setstate

已编辑:静态方法无权访问“ this”。潜在的问题是,如果您想在不同类中分离功能,您应该如何在reactjs中组织代码?调用这些类的方法的唯一方法就是将它们设为“静态”。真的是唯一方法吗?你该怎么办创建一个大类,以便所有方法都可以访问“ this”?

EDITED2:然后,我要做的是避免编写需要访问该状态的静态方法。特别是,我已经使用了一个诺言,将值返回给有权访问该状态的类。

 static Parse(cvs_string) {
    return new Promise((resolve, reject) => {
        Papa.parse(cvs_string, {
            header: true,
            skipEmptyLines: true,
            complete: (results) => resolve(results)
        });
    });
 }

EDITED3:但是,正如评论中所说,如果主要目的是提供辅助函数,那么构建一个也从Component扩展的类是没有意义的,所以最后:

import Papa from 'papaparse';

export const ParseCsv = (csv_string) => {
    return new Promise((resolve, reject) => {
        Papa.parse(csv_string, {
            header: true,
            skipEmptyLines: true,
            complete: (results) => resolve(results)
        });
    });
}

---- [上一页]

为什么这不起作用?我不应该在这里访问setstate吗?

import React, { Component } from 'react';
import Papa from 'papaparse';

class PapaParse extends Component {

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

  static Parse(cvs_string) {
    Papa.parse(cvs_string, {
      header: true,
      skipEmptyLines: true,
//    complete: (results) => { // this gives the same error
      complete: function(results) {
        PapaParse.updateData(results);
      }
    });
  }

  static updateData(results) {
    console.log(results); // results are the expected ones
    PapaParse.setState({data: results.data}); // here the error, or
    this.setState({data: results.data}); // here the same error
  }

}

export default PapaParse;

我可以通过将“ this”作为变量发送来解决这个问题,

PapaParse.Parse(response, this);

,然后在PapaParse组件中

static Parse(cvs_string, that) {
...
PapaParse.updateData(results, that);
...
static updateData(results, that) {
...
that.setState({data: results.data});

因此,我了解到,当我调用componenet的方法而不用“ tag”调用它而只是将其作为静态方法调用时,“ this”会丢失。

然后,我在这里要做的就是我应该做的?还是最好的方法是什么?

3 个答案:

答案 0 :(得分:2)

静态方法用于不依赖于类实例的代码,因为没有。静态方法没有很多好的用例,因为如果一个函数没有直接作为一个实体链接到一个类,那么它可能不需要成为它的一部分。用例之一是React组件getDerivedStateFromProps钩子,它是需要定义为方法的纯函数(因为它是应由框架作为类属性访问的钩子),它迫使开发人员不使用类实例并专注于功能输入和输出。

由于该方法特别需要类实例和setState实例方法,因此静态方法不适用于此处。这些方法都不应该是静态的:

class PapaParse extends Component {
  Parse(cvs_string) {
    Papa.parse(cvs_string, {
      header: true,
      skipEmptyLines: true,
      complete: (results) => {
        this.updateData(results);
      }
    });
  }

  updateData(results) {
    console.log(results);
    this.setState({data: results.data});
  }

}

这与this answer中说明的问题相同:

this.Parse = this.Parse.bind(this);

将静态方法绑定到类实例是一个错误,特别是在设计上不是单例的类中,并且该类应被实例化多次(React组件类是)。可能有多个类实例,这可能会导致错误和内存泄漏。

如果Parse方法应该在此类之外触发,则应以React惯用的方式进行,例如在父组件中获取PapaParse组件引用并对其访问实例方法:

// in constructor
this.papaParseRef = React.createRef();
...
// in render
<PapaParse ref={this.papaParseRef}/>

渲染后,该方法将以this.papaParseRef.current.Parse()的形式提供。

答案 1 :(得分:-1)

PapaParse.setState({data: results.data}); // here the error

应为this.setState,以便您引用实例,而不是类。

答案 2 :(得分:-1)

updatedata()声明为箭头函数。

updatedata=(results) => {
   //this.setState will work here
}