我知道这个问题被问了很多,我确实检查了提供的大多数其他答案,但我仍然不知道为什么会出现这个错误。
情况:
我有一个textinput
类,其中有一个简单的表单供用户输入名称。当用户提交按钮时,会调用对我的后端的REST调用,UI应该显示用户名。
我已经重写了App
类的函数componentDidMount
,以便在加载页面时对后端进行初始调用。这个调用有效,我从后台得到了正确的答案,UI也得到了更新。
但是当我从我的TextInput
类进行调用时,我得到了错误:
this2.setState不是函数
我相信发生这种情况是因为我从另一个类调用了函数,而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.log(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 rest调用中得到错误的主要类。
第二类是
import React, { Component } from 'react';
export default class TextInput extends Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(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.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
问题是,如何在getFormattedNameFromBackend方法中调用正确的this?
已解决:
错误在于错误地设置了Textinput字段的props。正确地说,它应该是
<TextInput callBack = {(name)=>this.getFormattedNameFromBackend(name)}/>
如果其他人遇到这个问题,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);
(以及BTW,this.setState.bind(this);
也是毫无意义的(