无法在回调中调用 setState
Cannot call setState in callback
我是 React 的新手,所以我知道我可能没有做对每件事。
我正在尝试在 onreadystatechange 回调中调用 setStatus,但在浏览器中出现错误。该代码对服务器执行 AJAX 调用,以查看建议的用户名是否已在数据库中。在 return onreadystatechange 被执行。如果用户名已经存在,我正在尝试为该用户名设置新的错误消息。
这是我的状态数据:
const initialState = {
firstname: "",
lastname: "",
username: "",
password: "",
email: "",
firstnameError: "",
lastnameError: "",
usernameError: "",
passwordError: "",
emailError: ""
};
class SignUpForm extends Component {
constructor() {
super();
this.state = initialState;
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.checkUserName = this.checkUserName.bind(this);
this.checkEmail = this.checkEmail.bind(this);
this.validateForm = this.validateForm.bind(this);
}
这是我在表单字段的更改处理程序中更新状态的地方:
handleChange(e) {
let target = e.target;
let value = target.value;
let name = target.name;
if (name === "username") {
value = value.toUpperCase();
}
this.setState({
[name]: value
});
}
这是我在浏览器中遇到错误的例程。发生错误的行在下面的行中用注释标记。
checkUserName() {
let usernameError = "";
let element = "";
let checkNameResponse = "";
let checkNameMessage = "";
let request = "";
let url = "";
let userName = "";
let requestData = "";
let checkNameResponseJSON = "";
request = new XMLHttpRequest();
if (request == null) alert("Unable to create checkDBForUSerNameRequest");
else {
url = "/php/CheckUsername.php";
userName = escape(document.getElementById("username").value);
requestData = JSON.stringify({
username: userName
});
request.onreadystatechange = function() {
if (request.readyState === 4 && request.status === 200) {
checkNameResponseJSON = JSON.parse(request.responseText);
checkNameResponse = checkNameResponseJSON.returncode;
checkNameMessage = checkNameResponseJSON.message;
element = document.getElementById("SignupIcon");
element.className = "displayIcon";
if (checkNameResponse === 0) {
element = document.getElementById("SignupIconFile");
element.src = "/images/YesButton.png";
element.alt = "Available";
this.setState({ usernameError: "" });
} else {
element = document.getElementById("SignupIconFile");
element.src = "/images/NoButton.png";
element.alt = "Not Available";
usernameError = checkNameMessage;
this.setState({ usernameError: usernameError }); // BROWSER ERROR
}
}
};
request.open("POST", url, true);
request.setRequestHeader("Content-Type", "application/json");
request.send(requestData);
}
}
这是来自浏览器错误的文本:
0: Object doesn't support property or method 'setState'
知道为什么会发生这种情况或如何解决吗?
您需要使用 .bind 或箭头函数绑定 onreadystatechange 函数,因为执行该函数时,它需要访问引用 class 上下文的正确 this
值。
request.onreadystatechange = function() {
// all logic here
}.bind(this)
或
request.onreadystatechange = () => {
//all logic here
}
错误是因为您使用的是 request.onreadystatechange = function() {}
而不是 request.onreadystatechange = () => {}
或 request.onreadystatechange = function() {}.bind(this)
当您使用 function()
时,this
的范围发生变化。
请记住 function() {}
和 () => {}
不 相同。
但是function(){}.bind(this)
和() => {}
是一样的。
我是 React 的新手,所以我知道我可能没有做对每件事。
我正在尝试在 onreadystatechange 回调中调用 setStatus,但在浏览器中出现错误。该代码对服务器执行 AJAX 调用,以查看建议的用户名是否已在数据库中。在 return onreadystatechange 被执行。如果用户名已经存在,我正在尝试为该用户名设置新的错误消息。
这是我的状态数据:
const initialState = {
firstname: "",
lastname: "",
username: "",
password: "",
email: "",
firstnameError: "",
lastnameError: "",
usernameError: "",
passwordError: "",
emailError: ""
};
class SignUpForm extends Component {
constructor() {
super();
this.state = initialState;
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.checkUserName = this.checkUserName.bind(this);
this.checkEmail = this.checkEmail.bind(this);
this.validateForm = this.validateForm.bind(this);
}
这是我在表单字段的更改处理程序中更新状态的地方:
handleChange(e) {
let target = e.target;
let value = target.value;
let name = target.name;
if (name === "username") {
value = value.toUpperCase();
}
this.setState({
[name]: value
});
}
这是我在浏览器中遇到错误的例程。发生错误的行在下面的行中用注释标记。
checkUserName() {
let usernameError = "";
let element = "";
let checkNameResponse = "";
let checkNameMessage = "";
let request = "";
let url = "";
let userName = "";
let requestData = "";
let checkNameResponseJSON = "";
request = new XMLHttpRequest();
if (request == null) alert("Unable to create checkDBForUSerNameRequest");
else {
url = "/php/CheckUsername.php";
userName = escape(document.getElementById("username").value);
requestData = JSON.stringify({
username: userName
});
request.onreadystatechange = function() {
if (request.readyState === 4 && request.status === 200) {
checkNameResponseJSON = JSON.parse(request.responseText);
checkNameResponse = checkNameResponseJSON.returncode;
checkNameMessage = checkNameResponseJSON.message;
element = document.getElementById("SignupIcon");
element.className = "displayIcon";
if (checkNameResponse === 0) {
element = document.getElementById("SignupIconFile");
element.src = "/images/YesButton.png";
element.alt = "Available";
this.setState({ usernameError: "" });
} else {
element = document.getElementById("SignupIconFile");
element.src = "/images/NoButton.png";
element.alt = "Not Available";
usernameError = checkNameMessage;
this.setState({ usernameError: usernameError }); // BROWSER ERROR
}
}
};
request.open("POST", url, true);
request.setRequestHeader("Content-Type", "application/json");
request.send(requestData);
}
}
这是来自浏览器错误的文本:
0: Object doesn't support property or method 'setState'
知道为什么会发生这种情况或如何解决吗?
您需要使用 .bind 或箭头函数绑定 onreadystatechange 函数,因为执行该函数时,它需要访问引用 class 上下文的正确 this
值。
request.onreadystatechange = function() {
// all logic here
}.bind(this)
或
request.onreadystatechange = () => {
//all logic here
}
错误是因为您使用的是 request.onreadystatechange = function() {}
而不是 request.onreadystatechange = () => {}
或 request.onreadystatechange = function() {}.bind(this)
当您使用 function()
时,this
的范围发生变化。
请记住 function() {}
和 () => {}
不 相同。
但是function(){}.bind(this)
和() => {}
是一样的。