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

Reactjs → static methods without access to "this", what's the alternative?

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

EDITED2:然后我所做的就是避免编写需要访问状态的静态方法。特别是,我已经承诺 return class 的值确实可以访问状态。

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

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

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

所以我知道当我调用一个组件的方法而不用 "tag" 调用它时 "this" 丢失了,而只是将它作为静态方法调用。

那么,我在这里做的就是我应该做的吗?或者最好的方法是什么?

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

应该是 this.setState 所以你引用了实例,而不是 class。

updatedata() 声明为箭头函数。

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

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

由于该方法需要class实例,特别是setState实例方法,静态方法在这里不适用。 None 这些方法应该是静态的:

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.Parse = this.Parse.bind(this);

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

如果 Parse 方法应该在此 class 之外触发,这应该以 React 惯用的方式完成,例如在父组件中获取 PapaParse 组件引用并访问其实例方法:

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

该方法将在呈现后作为 this.papaParseRef.current.Parse() 提供。