Я знаю, что этот вопрос часто задают, и я проверил большинство других предоставленных ответов, но до сих пор не могу понять, почему я получаю эту ошибку.
Ситуация:
У меня есть класс textinput, в котором у меня есть простая форма для ввода имени пользователем. Когда пользователь отправляет кнопку, вызывается REST-вызов моей серверной части, и пользовательский интерфейс должен отображать имя пользователя.
Я переопределил функцию componentDidMount моего класса App, чтобы иметь первоначальный вызов моего бэкэнда при загрузке страницы. Этот вызов работает, я получаю правильный ответ от своей серверной части, и пользовательский интерфейс обновляется.
Но когда я звоню из своего класса TextInput, я получаю сообщение об ошибке:
this2.setState is not a function
Я считаю, что это происходит потому, что я вызываю функцию из другого класса, а this state настроен неправильно. Я пытался связать все, но это ничего не меняло. Если у кого-то есть представление о том, что я делаю неправильно, это было бы очень полезно!
У меня есть следующие занятия:
import React, { Component } from 'react';
import logo from './logo.svg';
import Greeting from './components/greeting';
import TextInput from './components/textInput';
import './App.css';
const axios = require('axios');
class App extends Component {
constructor(props) {
super(props);
this.state = {name: "World"};
this.getFormattedNameFromBackend.bind(this);
this.setState.bind(this);
}
componentDidMount() {
this.getFormattedNameFromBackend(this.state.name);
}
getFormattedNameFromBackend(name) {
axios({
method:'get',
url:'http://localhost:8080/hello?name=' + name
}).then((response) => {
this.setState({ name : response.data.name});
}).catch(function(error){
console.info(error);
});
}
render() {
return (
<div className = "App">
<header className = "App-header">
<img src = {logo} className = "App-logo" alt = "logo" />
<Greeting data = {this.state}/>
<TextInput callBack = {this.getFormattedNameFromBackend}/>
</header>
</div>
);
}
}
export default App;
Это основной класс, в котором я получаю ошибку при вызове отдыха axios.
второй класс таков:
import React, { Component } from 'react';
export default class TextInput extends Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChangeEvent = this.handleChangeEvent.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChangeEvent(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
this.props.callBack(this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit= {this.handleSubmit}>
<label>
Name:
<input type = "text" value = {this.state.value} onChange = {this.handleChangeEvent} />
</label>
<input type = "submit" value = "Submit" />
</form>
);
}
}
Итак, вопрос в том, как мне правильно вызвать это в методе getFormattedNameFromBackend?
Решено:
ошибка заключалась в неправильной установке реквизита Textinputfield. Правильно должно быть
<TextInput callBack = {(name)=>this.getFormattedNameFromBackend(name)}/>
в то время, когда я получаю сообщение об ошибке, это объект типа textinput. Но как мне это изменить?
Попробуйте посмотреть ссылку, которую я предоставил, проще всего привязать ее через закрытие onSubmit= (e) => {this.handleSubmit(e)}. Взгляните и на это: responsejs.org/docs/handling-events.html
Я пытаюсь это сделать, но на самом деле у меня возникают синтаксические ошибки. : / Сейчас я пробую это: onSubmit = {(e) => this.handleSubmit (e)}, но это дает мне ту же ошибку, что и раньше
взгляните на это, вроде работает jsfiddle.net/n5u2wwjg/233958
Большое спасибо, ошибка была "<TextInput callBack = {(name) => this.getFormattedNameFromBackend (name)} />", я искал не в том направлении TT. Вы мне очень помогли, спасибо
Добавлен ответ для других, интересующихся этим. не стесняйтесь отмечать это как решенное!



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Если кто-то еще задаст этот вопрос, https://reactjs.org/docs/handling-events.html довольно хорошо объясняет, почему это происходит.
Короче говоря, this не привязан, когда вызываются обратные вызовы событий.
Самый простой способ исправить это - заключить это:
onSubmit = {(e) => {this.handleSubmit(e)} (хотя при этом каждый раз создается новый экземпляр функции, поэтому следует соблюдать осторожность при использовании этого метода).
То, как вы это решили, работает, просто избегая привязки, если this вообще, но ваша первоначальная проблема заключалась в том, что строка
this.getFormattedNameFromBackend.bind(this);
не делает именно то, что вы думаете.
.bind() возвращает новую функцию, которая обертывает исходную функцию, но вы ничего не делаете с этой новой функцией. .bind() не изменяет исходную функцию, поэтому this.getFormattedNameFromBackend остается несвязанным, и поэтому <TextInput callBack = {this.getFormattedNameFromBackend}/> не работает.
Если бы вы написали эту строку как:
this.getFormattedNameFromBackend = this.getFormattedNameFromBackend.bind(this);
... (как вы это делаете в своем классе TextInput) он будет правильно привязан, и callBack = {this.getFormattedNameFromBackend} будет работать.
Как я уже сказал, записывая его как callBack = {() => this.getFormattedNameFromBackend()}, вы в любом случае избегаете проблемы привязки, поэтому вы можете просто удалить this.getFormattedNameFromBackend.bind(this); (и, кстати, this.setState.bind(this); тоже довольно бессмысленный)
Похоже,
thisссылается не на тот объект. Попробуйте распечатать, что такоеthisтам, где он возникает, или прочитать этот stackoverflow.com/questions/45041878/closures-in-react Короче говоря, события в функции рендеринга действуют на объектыevent, а не на класс, для которого определена функция рендеринга, потому что события асинхронны ...