当前位置: 首页 > 知识库问答 >
问题:

使用useEffects超过最大更新深度

杨晓博
2023-03-14

当我试图设置表单错误对象时,我遇到了这个问题。基本上,我想在每个输入字段下方显示错误。作为回应,我得到了一个对象数组,我如何设置我的错误对象?

错误-超过了最大更新深度。当组件在useEffect内部调用setState,但useEffect没有依赖关系数组,或者每次呈现时依赖关系之一发生变化时,就会发生这种情况。

import axios from "axios";
import React, { useState, useEffect, useCallback } from "react";
import { Link } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { register } from "../actions/userActions";
const Register = () => {
    const [countriesList, setCountriesList] = useState("");
    const [userRegistration, setUserRegistration] = useState({
        firstName: "",
        lastName: "",
        email: "",
        password: "",
        fullAddress: "",
        city: "",
        zipCode: "",
        country: "",
        phone: "",
        terms: true,
    });
    const [userRegistrationError, setUserRegistrationError] = useState({
        firstNameError: "",
        lastNameError: "",
        emailError: "",
        passwordError: "",
        fullAddressError: "",
        cityError: "",
        zipCodeError: "",
        countryError: "",
        phoneError: "",
        termsError: "",
    });
    const dispatch = useDispatch();

    const userRegister = useSelector((state) => state.userRegister);
    const { loading, errors, success } = userRegister;

    useEffect(() => {
        const countries = async () => {
            try {
                const { data } = await axios.get(
                    `https://restcountries.eu/rest/v2/all`
                );
                setCountriesList(data);
            } catch (err) {
                console.error(err);
            }
        };
        countries();
    }, []);

    useEffect(() => {
        const handleErrors = (errors) => {
            errors.map((error) => {
                if (error.param === "firstname") {
                    setUserRegistrationError({
                        ...userRegistrationError,
                        firstNameError: error.msg,
                    });
                }
                if (error.param === "email") {
                    setUserRegistrationError({
                        ...userRegistrationError,
                        emailError: error.msg,
                    });
                }
                return null;
            });
        };
        if (errors) {
            handleErrors(errors);
        }
    }, [errors, setUserRegistrationError]);

    const handleChange = (e) => {
        const name = e.target.name;
        const value = e.target.value;
        setUserRegistration({ ...userRegistration, [name]: value });
    };
    const handleChkChange = (e) => {
        const checked = e.target.checked;
        console.log(checked);
        setUserRegistration({ ...userRegistration, terms: checked });
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        try {
            dispatch(register());
        } catch (error) {
            console.error(error);
        }
    };
    return (
        <div className="form_container">
            <form action="" onSubmit={handleSubmit}>
                <div className="row no-gutters">
                    <div className="col-6 pr-1">
                        <div className="form-group">
                            <div className="form-group">
                                <input
                                    type="text"
                                    name="firstName"
                                    className="form-control"
                                    placeholder="First Name*"
                                    value={userRegistration.firstName}
                                    onChange={handleChange}
                                />
                                <p className="form-vald-error">
                                    {userRegistrationError.firstNameError &&
                                        userRegistrationError.firstNameError}
                                </p>
                            </div>
                        </div>
                    </div>
                    <div className="col-6 pr-1">
                        <div className="form-group">
                            <input
                                type="text"
                                className="form-control"
                                name="lastName"
                                placeholder="Last Name*"
                                value={userRegistration.lastName}
                                onChange={handleChange}
                            />
                            <p className="form-vald-error">
                                {userRegistrationError.lastNameError &&
                                    userRegistrationError.lastNameError}
                            </p>
                        </div>
                    </div>
                </div>
                <hr />
                <div className="private box">
                    <div className="row no-gutters">
                        <div className="col-6 pr-1">
                            <div className="form-group">
                                <input
                                    type="email"
                                    className="form-control"
                                    name="email"
                                    id="email_2"
                                    placeholder="Email*"
                                    value={userRegistration.email}
                                    onChange={handleChange}
                                />
                                <p className="form-vald-error">
                                    {userRegistrationError.emailError &&
                                        userRegistrationError.emailError}
                                </p>
                            </div>
                        </div>
                        <div className="col-6 pl-1">
                            <div className="form-group">
                                <input
                                    type="password"
                                    className="form-control"
                                    name="password"
                                    id="password_in_2"
                                    placeholder="Password*"
                                    value={userRegistration.password}
                                    onChange={handleChange}
                                />
                                <p className="form-vald-error">
                                    {userRegistrationError.passwordError &&
                                        userRegistrationError.passwordError}
                                </p>
                            </div>
                        </div>
                        <div className="col-12">
                            <div className="form-group">
                                <input
                                    type="text"
                                    name="fullAddress"
                                    className="form-control"
                                    placeholder="Full Address*"
                                    value={userRegistration.fullAddress}
                                    onChange={handleChange}
                                />
                                <p className="form-vald-error">
                                    {userRegistrationError.fullAddressError &&
                                        userRegistrationError.fullAddressError}
                                </p>
                            </div>
                        </div>
                    </div>
                    {/* /row */}
                    <div className="row no-gutters">
                        <div className="col-6 pr-1">
                            <div className="form-group">
                                <input
                                    type="text"
                                    className="form-control"
                                    placeholder="City*"
                                    name="city"
                                    value={userRegistration.city}
                                    onChange={handleChange}
                                />
                                <p className="form-vald-error">
                                    {userRegistrationError.cityError &&
                                        userRegistrationError.cityError}
                                </p>
                            </div>
                        </div>
                        <div className="col-6 pl-1">
                            <div className="form-group">
                                <input
                                    type="text"
                                    className="form-control"
                                    placeholder="Postal Code*"
                                    name="zipCode"
                                    value={userRegistration.zipCode}
                                    onChange={handleChange}
                                />
                                <p className="form-vald-error">
                                    {userRegistrationError.zipCodeError &&
                                        userRegistrationError.zipCodeError}
                                </p>
                            </div>
                        </div>
                    </div>
                    {/* /row */}
                    <div className="row no-gutters">
                        <div className="col-6 pr-1">
                            <div className="form-group">
                                <div className="custom-select-form">
                                    <select
                                        className="wide add_bottom_10 form-control"
                                        name="country"
                                        id="country"
                                        value={userRegistration.country}
                                        onChange={handleChange}
                                    >
                                        <option>Country*</option>
                                        {countriesList &&
                                            countriesList.map((country) => (
                                                <option
                                                    key={country.alpha2Code}
                                                    value={country.alpha2Code}
                                                >
                                                    {country.name}
                                                </option>
                                            ))}
                                    </select>
                                    <p className="form-vald-error">
                                        {userRegistrationError.countryError &&
                                            userRegistrationError.countryError}
                                    </p>
                                </div>
                            </div>
                        </div>
                        <div className="col-6 pl-1">
                            <div className="form-group">
                                <input
                                    type="text"
                                    className="form-control"
                                    placeholder="Telephone *"
                                    name="phone"
                                    value={userRegistration.phone}
                                    onChange={handleChange}
                                />
                                <p className="form-vald-error">
                                    {userRegistrationError.phoneError &&
                                        userRegistrationError.phoneError}
                                </p>
                            </div>
                        </div>
                    </div>
                    {/* /row */}
                </div>
                <hr />
                <div className="form-group">
                    <label className="container_check">
                        Accept <Link to="#0">Terms and conditions</Link>
                        <input
                            type="checkbox"
                            name="terms"
                            checked={userRegistration.terms}
                            onChange={handleChkChange}
                        />
                        <span className="checkmark" />
                        <p className="form-vald-error">
                            {userRegistrationError.termsError &&
                                userRegistrationError.termsError}
                        </p>
                    </label>
                </div>
                <div className="text-center">
                    <input
                        type="submit"
                        defaultValue="Register"
                        className="btn_1 full-width"
                    />
                </div>
            </form>
        </div>
    );
};

export default Register;

共有2个答案

刁星渊
2023-03-14

第二个useEffect有问题,第一次更新状态userRegistrationError时,组件重新呈现并重新执行useeffect,因为依赖关系userRegistrationError已更改,并且该过程再次重复,因为每次呈现时状态都会更新。

 useEffect(() => {
        const handleErrors = (errors) => {
            errors.map((error) => {
                if (error.param === "firstname") {
                    setUserRegistrationError({
                        ...userRegistrationError,
                        firstNameError: error.msg,
                    });
                }
                if (error.param === "email") {
                    setUserRegistrationError({
                        ...userRegistrationError,
                        emailError: error.msg,
                    });
                }
                return null;
            });
        };
        if (errors) {
            handleErrors(errors);
        }
    }, [errors, setUserRegistrationError ]); //replace userRegistrationError by setUserRegistrationError
别烨熠
2023-03-14

您的效果取决于用户注册错误,它是一个基于引用的对象。每次使用效果运行时,setUserRegistration错误都会创建一个新的对象引用,这会导致无限循环,因为引用与上一个引用不同。

避免此问题并保留正确引用的一种方法是传递回调函数来设置用户注册错误而不是值。这样,用户注册错误不再是依赖项,而是函数的参数:

useEffect(() => {
    const handleErrors = (errors) => {
        errors.forEach((error) => {
            if (error.param === "firstName") {
                // here you pass a callback function instead, and userRegistrationError is no longer a dependency
                // and returns the next state as expected
                setUserRegistrationError(userRegistrationError => ({
                    ...userRegistrationError,
                    firstNameError: error.msg,
                }));
            }
            if (error.param === "email") {
                setUserRegistrationError(userRegistrationError => ({
                    ...userRegistrationError,
                    emailError: error.msg,
                }));
            }
        });
    };
    if (errors) {
        handleErrors(errors);
    }
}, [errors, setUserRegistrationError]);
 类似资料:
  • 超过了最大更新深度。当组件重复调用组件WillUpdate或组件DidUpdate中的setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。 这是bossinfo.js 这是user.redux.js 你为什么一直报告这个问题?这是指向错误的方向吗?寻求帮助

  • 尝试在基本应用程序中包含 react-table,该应用程序在字段中接受输入,在字段内容更改时将其存储在组件状态中,然后在按下按钮时从 Github 获取数据。 在我加上线之前一切正常 该页面可以正常加载,但是当输入字段改变时(即你在其中输入),应用程序崩溃并显示错误: 错误:超过了最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的set

  • 我遇到一个错误: 超过了最大更新深度。当组件重复调用componentWillUpdate或componentDidUpdate内部的setState时,会发生这种情况。React限制嵌套更新的数量,以防止无限循环。 我的代码是: 我有另一个使用路由器切换页面的组件,以及一个包含登录页面的邮件组件。

  • 当我运行我的代码时,我收到了这个错误。 超过了最大更新深度。当组件重复调用组件WillUpdate或组件DidUpdate中的setState时,可能会发生这种情况。React限制嵌套更新的数量以防止无限循环。 这是代码。它在引用。 我按照React网站上的文章所说的方式设置了我的东西,它“来了”于这个简洁的控制台类型,这就是我产生上述代码的地方。我对React、JSX和Javascript(以及

  • 我有以下组件:- 我得到了错误:- 我怀疑它必须对多次调用setState的Submit按钮(onClick)做一些事情,但是我似乎无法解决问题。 因此,我有以下问题:- 如何修复点击()? 我想点击开始游戏按钮,然后触发 并 这样我就可以填满套牌,套牌1和套牌2。有没有办法做到这一点?目前,我已经创建了一个这取决于正在填充的甲板,这是用钩子做的正确方法吗? 谢谢你的帮助和时间!

  • 我正在使用FullCalendar进行反应,我正在与状态作斗争……它返回以下消息: 错误:超过最大更新深度。当组件在componentWillUpdate或componentDidUpdate内重复调用setState时,可能会发生这种情况。React限制嵌套更新的数量,以防止无限循环。 我删除了代码中所有不必要的部分。 如果您想让我提供更多信息,请告诉我。欢迎任何反馈/想法!谢谢