Reactjs → статические методы без доступа к «this», какова альтернатива? - PullRequest
0 голосов
/ 16 сентября 2018

РЕДАКТИРОВАНИЕ: Статические методы не имеют доступа к «этому». Основной вопрос заключается в том, как вы должны организовать код в реагирующих, если вы хотите разделить функциональные возможности по разным классам? единственный способ вызвать методы этих классов - сделать их статическими. Это действительно единственный способ? Что ты должен делать? Создать один большой класс, чтобы все методы имели доступ к «this»?

РЕДАКТИРОВАНИЕ2: Затем я избежал написания статического метода, который должен иметь доступ к состоянию. В частности, я использовал обещание вернуть значение классу, у которого есть доступ к состоянию.

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

---- [предыдущий]

Почему это не работает? Разве я не должен иметь здесь доступ к серверу?

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

Так что я понимаю, что «this» теряется, когда я вызываю метод компонентной сети, не вызывая его с «tag», а просто вызываю его как статический метод.

Тогда, что я здесь делаю, это то, что я должен делать? Или какой лучший способ сделать это?

Ответы [ 3 ]

0 голосов
/ 16 сентября 2018

Объявите updatedata() как функцию стрелки.

updatedata=(results) => {
   //this.setState will work here
}
0 голосов
/ 16 сентября 2018

Статические методы предназначены для кода, который не зависит от экземпляра класса, потому что его нет. Существует не так много хороших вариантов использования статических методов, потому что, если функция не связана напрямую с классом как сущностью, она, возможно, не должна быть ее частью. Одним из вариантов использования является компонент 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.Parse = this.Parse.bind(this);

Ошибочно привязывать статический метод к экземпляру класса, особенно в классе, который не является одноэлементным по своему дизайну и ожидается, что его экземпляр будет создан несколько раз (класс компонента React есть). Может быть несколько экземпляров классов, это может привести к ошибкам и утечкам памяти.

Если Parse метод должен запускаться за пределами этого класса, это должно быть сделано способом, идиоматичным для React, например, получить PapaParse компонент ref в родительском компоненте и вызвать метод экземпляра для него:

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

Метод будет доступен как this.papaParseRef.current.Parse() после рендеринга.

0 голосов
/ 16 сентября 2018

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

Должно быть this.setState, поэтому вы ссылаетесь на экземпляр, а не на класс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...