reactjs - 当我使用句柄登录方法时,它会导致“超出最大更新深度”
问题描述
该项目使用 firebase 作为后端,React 作为前端技术。我使用 axios 调用 APIs,这是我在登录组件中使用登录方法时的记帐上下文,它会导致:
超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。React 限制了嵌套更新的数量以防止无限循环。
可能是什么问题?使用异步函数作为方法?请注意仅处理登录方法。
import React, { Component } from "react";
import validation from "../../utils/utils";
import axios, { request } from "../../config/axios/axios";
import firebase from "../../config/firebase/firebase";
export const Account = React.createContext();
class DataProvider extends Component {
state = {
view: false,
hintText: "",
createAccount: {
fullName: {
value: "",
hint: false,
hintText: ""
},
username: {
value: "",
hint: false,
hintText: ""
},
phoneNumber: {
value: "",
hint: false,
hintText: ""
},
email: {
value: "",
hint: false,
hintText: ""
},
password: {
value: "",
hint: false,
hintText: ""
}
},
login: {
username: {
value: "",
hint: false,
hintText: ""
},
password: {
value: "",
hint: false,
hintText: ""
}
},
createAccountStatus: false,
FacebookReturnResult: false,
loginStatus: false,
loginIsLoading: false,
userProfileData: {
profileEdit: {
fullName: {
value: "",
hint: false,
hintText: ""
},
email: {
value: "",
hint: false,
hintText: ""
},
phoneNumber: {
value: "",
hint: false,
hintText: ""
},
country: {
value: "",
hint: false,
hintText: ""
},
state: {
value: "",
hint: false,
hintText: ""
},
district: {
value: "",
hint: false,
hintText: ""
}
}
}
};
onChange = (e, partName) => {
const { name, value } = e.target;
const newState = { ...this.state };
newState[partName][name].value = value;
if (partName === "createAccount") {
if (name === "fullName" && value.length <= 3) {
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText = "Please Check Your Fullname";
console.log("wrong");
} else if (name === "fullName" && value.length > 3) {
console.log("object");
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
if (name === "username" && value.length <= 3) {
// console.log(123);
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText =
"username should be at 4 characters";
} else if (name === "username" && value.length > 3) {
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
if (name === "password" && value.length < 6) {
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText =
"password should be at least 6 characters";
} else if (name === "password" && value.length >= 6) {
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
if (name === "phoneNumber" && value.length < 11) {
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText =
"Please Check Your Phone Number";
} else if (name === "phoneNumber" && value.length === 11) {
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
if (name === "email" && !validation().Mail(value)) {
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText =
"Please Check Your Email Address";
} else if (name === "email" && validation().Mail(value)) {
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
}
if (partName === "login") {
}
this.setState({
...newState
});
};
handleCreateAccount = () => {
const { createAccount } = this.state;
axios
.post("/user/signup", {
email: createAccount.email.value,
name: createAccount.fullName.value,
password: createAccount.password.value
})
.then(({ data }) => {
console.log(data);
const newState = { ...this.state };
if (data.hasOwnProperty("error")) {
newState.view = true;
newState.hintText = data.error.message;
this.setState(
{
...newState
},
() => {
setTimeout(() => {
newState.view = false;
newState.hintText = "";
this.setState({
...newState
});
}, 2000);
}
);
} else if (data.hasOwnProperty("user")) {
newState.createAccountStatus = true;
this.setState({
...newState
});
}
});
};
handleLogin = async () => {
const newState = { ...this.state };
const { login } = this.state;
this.setState({
loginIsLoading: true
});
try {
let result = await firebase
.auth()
.signInWithEmailAndPassword(login.username.value, login.password.value);
let token = await firebase.auth().currentUser.getIdToken(true);
if (token) {
console.log(token);
let auth = `Bearer ${token}`;
request
.get("/user/profile", {
headers: {
Authorization: auth,
"Content-Type": "application/json"
}
})
.then(({ data }) => {
console.log(data);
newState.userProfileData.profileData = data.data;
newState.userProfileData.profileEdit.fullName.value =
data.data.displayName;
newState.userProfileData.profileEdit.email.value = data.data.email;
newState.userProfileData.profileEdit.phoneNumber.value =
data.data.phoneNumber;
newState.userProfileData.selectedPhoto =
data.data.updatedPhotoBase64;
this.setState({ ...newState }, () => {
request
.get("/user/friends", {
headers: {
Authorization: auth,
"Content-Type": "application/json"
}
})
.then(({ data }) => {
console.log(data);
newState.loginIsLoading = false;
newState.loginStatus = true;
newState.userProfileData.friendsList = data.data;
newState.userProfileData.profileDataStatus = true;
this.setState({ ...newState });
});
});
});
}
} catch (error) {
console.log("error:" + error);
}
};
render() {
const {
createAccount,
login,
profileEdit,
view,
hintText,
createAccountStatus,
FacebookReturnResult,
loginStatus,
loginIsLoading,
userProfileData
} = this.state;
return (
<Account.Provider
value={{
loginIsLoading,
loginStatus,
profileEdit,
createAccount,
onChange: this.onChange,
login,
handleCreateAccount: this.handleCreateAccount,
view,
hintText,
createAccountStatus,
FacebookReturnResult,
handleLogin: this.handleLogin,
userProfileData: userProfileData
}}
>
{this.props.children}
</Account.Provider>
);
}
}
export default DataProvider;
hint: false,
hintText: ""
},
district: {
value: "",
hint: false,
hintText: ""
}
}
}
};
onChange = (e, partName) => {
const { name, value } = e.target;
const newState = { ...this.state };
newState[partName][name].value = value;
if (partName === "createAccount") {
if (name === "fullName" && value.length <= 3) {
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText = "Please Check Your Fullname";
console.log("wrong");
} else if (name === "fullName" && value.length > 3) {
console.log("object");
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
if (name === "username" && value.length <= 3) {
// console.log(123);
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText =
"username should be at 4 characters";
} else if (name === "username" && value.length > 3) {
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
if (name === "password" && value.length < 6) {
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText =
"password should be at least 6 characters";
} else if (name === "password" && value.length >= 6) {
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
if (name === "phoneNumber" && value.length < 11) {
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText =
"Please Check Your Phone Number";
} else if (name === "phoneNumber" && value.length === 11) {
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
if (name === "email" && !validation().Mail(value)) {
newState.createAccount[name].hint = true;
newState.createAccount[name].hintText =
"Please Check Your Email Address";
} else if (name === "email" && validation().Mail(value)) {
newState.createAccount[name].hint = false;
newState.createAccount[name].hintText = "";
}
}
if (partName === "login") {
}
this.setState({
...newState
});
};
handleCreateAccount = () => {
const { createAccount } = this.state;
axios
.post("/user/signup", {
email: createAccount.email.value,
name: createAccount.fullName.value,
password: createAccount.password.value
})
.then(({ data }) => {
console.log(data);
const newState = { ...this.state };
if (data.hasOwnProperty("error")) {
newState.view = true;
newState.hintText = data.error.message;
this.setState(
{
...newState
},
() => {
setTimeout(() => {
newState.view = false;
newState.hintText = "";
this.setState({
...newState
});
}, 2000);
}
);
} else if (data.hasOwnProperty("user")) {
newState.createAccountStatus = true;
this.setState({
...newState
});
}
});
};
handleLogin = async () => {
const newState = { ...this.state };
const { login } = this.state;
this.setState({
loginIsLoading: true
});
try {
let result = await firebase
.auth()
.signInWithEmailAndPassword(login.username.value, login.password.value);
let token = await firebase.auth().currentUser.getIdToken(true);
if (token) {
console.log(token);
let auth = `Bearer ${token}`;
request
.get("/user/profile", {
headers: {
Authorization: auth,
"Content-Type": "application/json"
}
})
.then(({ data }) => {
console.log(data);
newState.userProfileData.profileData = data.data;
newState.userProfileData.profileEdit.fullName.value =
data.data.displayName;
newState.userProfileData.profileEdit.email.value = data.data.email;
newState.userProfileData.profileEdit.phoneNumber.value =
data.data.phoneNumber;
newState.userProfileData.selectedPhoto =
data.data.updatedPhotoBase64;
this.setState({ ...newState }, () => {
request
.get("/user/friends", {
headers: {
Authorization: auth,
"Content-Type": "application/json"
}
})
.then(({ data }) => {
console.log(data);
newState.loginIsLoading = false;
newState.loginStatus = true;
newState.userProfileData.friendsList = data.data;
newState.userProfileData.profileDataStatus = true;
this.setState({ ...newState });
});
});
});
}
} catch (error) {
console.log("error:" + error);
}
};
render() {
const {
createAccount,
login,
profileEdit,
view,
hintText,
createAccountStatus,
FacebookReturnResult,
loginStatus,
loginIsLoading,
userProfileData
} = this.state;
return (
<Account.Provider
value={{
loginIsLoading,
loginStatus,
profileEdit,
createAccount,
onChange: this.onChange,
login,
handleCreateAccount: this.handleCreateAccount,
view,
hintText,
createAccountStatus,
FacebookReturnResult,
handleLogin: this.handleLogin,
userProfileData: userProfileData
}}
>
{this.props.children}
</Account.Provider>
);
}
}
export default DataProvider;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
解决方案
您不能在重新渲染很多的代码部分中使用 this.setState ,并且您必须从重新渲染的组件中获取 this.setState 之外的部分
推荐阅读
- mysql - 对两列进行分组时删除冗余
- android - 从 MapActivity 中选择 Address 并返回 MainActivity
- javascript - 如何在 WebView 中添加 JavaScript 函数并稍后在提交 reCAPTCHA 时从 HTML 调用它
- php - PHP如何将单个数组转换为多维数组?
- php - PHP - pdo presistent 连接和致命错误
- amazon-web-services - 如何使用 Fargate 在 AWS ECS 中正在运行的容器中运行命令
- java - 使用 mysql 将 ID_Column 值增加 1
- c - libgit2 (git_status_byindex(status, i))->head_to_index->old_file.path 为 NULL,为什么?(libgit 状态示例)
- flutter - 是否可以在颤动中播放设备的默认通知声音?
- vba - VBA:根据单元格值过滤数据并填写到另一张表