首页 > 解决方案 > 当我使用句柄登录方法时,它会导致“超出最大更新深度”

问题描述

该项目使用 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>

标签: reactjs

解决方案


您不能在重新渲染很多的代码部分中使用 this.setState ,并且您必须从重新渲染的组件中获取 this.setState 之外的部分


推荐阅读