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