This.setState undefined

Я продолжаю видеть ответы, которые говорят, чтобы использовать = > или .bind(это), но ни один из этих решений не работал.

import React, { Component } from 'react';
import { View, Text, TextInput, StyleSheet } from 'react-native';

export default class MyWeatherApp extends Component {
  constructor(props) {
  super(props);

  this.state = {};
}

getInitialState() {
  return {
    zip: '',
    forecast: null,
  };
}

_handleTextChange(event) {
  var zip = event.nativeEvent.text;
  this.setState({zip: zip});
}

Решение:

_handleTextChange = (event) => {
  var zip = event.nativeEvent.text;
  this.setState({zip: zip});
  alert('click');
}

Ответ 1

Когда вы extend React.Component с синтаксисом класса ES2015, вам необходимо привязать обработчики действий к контексту вашего класса.

Попробуйте следующее: onChange={e => _handleTextChange(e)}

Как правило, лучше не использовать функции стрелок или методы bind внутри render, поскольку он генерирует новую копию функции при любом вызове render. Объявление функции перемещения в class constructor.

Я лично предпочитаю использовать функции стрелок как свойства класса в этом случае

class MyClass extends React.Component {

  handleClick = () => {
    // your logic
  };

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

Это не входит в спецификацию ES2015, но babel stage-0 preset поддерживает этот синтаксис

Вы можете больше узнать о привязке контекста в React в этой статье

Ответ 2

Позвольте мне написать это подробно. Поскольку мне приходилось тратить много времени на исследования, и я не хочу, чтобы кто-то повторил это...

Если вы не используете функцию стрелки, вам нужно привязать this как Line '9'

class MyClass extends React.Component {

  handleButtonClick(){
    console.log("Hello from here");
  };

  render() {
    return (
      <button onClick={this.handleButtonClick.bind(this)}>Click me</button>
    );
  }
}

Другой способ - использовать функцию ES6 Arrow. В этом случае вам не нужно связывать 'this'. Установка "Babel stage-1 preset" будет поддерживать это.

Выполните следующую команду в своем проекте:

npm i babel-preset-stage-1 --save

Ваш .babelrc будет выглядеть следующим образом. Специально "этап-1" в предустановке.

{
  "presets": ["es2015", "react", "stage-1"],
  "env": {
    "development": {
      "plugins": ["react-hot-loader/babel"]
    }
  }
}

Ваш компонент будет таким, как я сказал:

class MyClass extends React.Component {

      handleButtonClick = () => {
        console.log("Hello from here");
      };

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

Ответ 3

Проблема была: у меня была эта ОШИБКА: this.setState не является функцией

Учитывая, что я связывал свою функцию с состоянием в конструкторе компонентов, вот так:

 this.getRequestData = this.getRequestData.bind(this);

и моя функция была:

getRequestData(){
    axios.post('http://example.com/getInfo', jsonData)
                        .then(function (res) {
                            console.log(res);
                        })
                        .catch(function (error) {
                            console.log(error);
                        });
                        this.setState({ stateVaribale });
                    })
}

Решение состоит в том, чтобы использовать arrow functions вместо использования keyword function в запросе axios, так как это вызывает путаницу в реакции на обращение к функции в запросе axios вместо состояния компонента.

getRequestData(){
axios.post('http://example.com/getInfo', jsonData)
                        .then(res => {
                        console.log(res);
                        })
                        .catch(error => {
                            console.log(error);
                        });
                        this.setState({ stateVaribale });
                    })}

Ответ 4

также вы можете связать это в constructor следующим образом

class MyClass extends React.Component {
  constructor(props){
    super(props);
    this.handleButtonClick = this.handleButtonClick.bind(this);
 }
  handleButtonClick(){
    console.log("Hello from here");
  }

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

Ответ 5

работает и для реагирующего на себя, когда вы используете толстые функции стрелок внутри методов, которые вы вызываете для другой функции. например .then((response) => { this.setState({....}) }

Ответ 6

Всякий раз, когда вы используете это внутри вызова API, как запрос axios. Есть случаи, когда ваш контекст "this" остается неопределенным. Разработка нескольких из них here-:

'

import react from 'React'
class Test extends from React.Component {
constructor() {
super();
this.state = {
data: '',
error: ''
}
}
componentDidMount() {
url = 'http://abc.go.com';
axios.get(url).then(function(resposne) {   // Everything fine till now
this.setState({ data: response });   //Oops this context is undefined
}
).catch(function(err) {
 this.setState({ error: err });       // again this context remains to be undefined
});
}
render() {
return ( <div>this.state.data</div> ) 
}
}'

когда вы запустите приведенный выше код, вы определенно получите ошибку типа, например, вызывается setState of undefined, что-то похожее на это.

Как вы можете решить это? Есть два метода, которые вы можете использовать, чтобы решить этот конкретный тип question-:

Во-первых, вы можете определить переменную внутри функции, в которой вы будете вызывать API, и присвоить ей значение this, и из этой переменной вы можете ссылаться на ваш объект состояния.

import react from 'React'
class Test extends React.Component
{
  constructor() { 
     super();
     this.state = {
       data: '',
       error: ''
  };
  componentDidMount() {
   let url = 'http://abc.go.com';
   currentContext = this;   // variable to be assigned this context
   axios.get(url).then(function(resposne) {   // Everything fine till now
   currentContext.setState({ data: response });   //Oops this context is undefined
   }
   ).catch(function(err) {
  currentContext.setState({ error: err });       // again this context remains to be undefined
 });
  }
 render() {
  return ( <div>this.state.data</div> ) 
 }
 }

Второй метод, который вы можете использовать, определив функцию стрелки в аксиосах, как показано ниже

axios.get(url).then((response) => {
  this.setState({ data: response })     //will always be bound to the this context
})