【问题标题】:ReactJS: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and stateReactJS:在现有状态转换期间无法更新(例如在 `render` 中)。渲染方法应该是 props 和 state 的纯函数
【发布时间】:2021-08-04 15:16:04
【问题描述】:

您好,我是 ReactJS 的新手,我正在使用库 react-bootstrap4-form-validation 来验证我的表单。从文档中有用于重置表单验证的功能。从文档中可以看到使用触发按钮onClick 重置表单验证的示例,例如this。对于一个条件,我需要重置验证,但不是在触发按钮 onClick 时,而是在父组件的道具发生变化时。由于这些需求,我还创建了一个函数 (useCompare),用于比较从父组件接收到的 props。

总之,我想重置我的表单,当从父组件收到的props发生变化时,代码如下所示。

import React, { useRef } from "react";
import { ValidationForm, TextInput } from 'react-bootstrap4-form-validation';
import { useCompare } from '../../services/compare-props';

function TestForm({ form }) {
  const formRefs = useRef();
  

    const handleSubmit = (e, formData, inputs) => {
        e.preventDefault();
        console.log(formData)
    }

    if ( !useCompare(form) ) {
        resetForm()
    }


  function resetForm() {
    let formRef = formRefs.current;
    formRef != null ? formRef.resetValidationState(true) : null;
  }

    return (
        <div className="row justify-content-center">
            <div className="col-md-6 col-sm-10">
                <div className="shadow-sm p-3 mb-5 bg-white rounded border">
                    <h6>{form.labelForm}</h6>
                    <hr />
                    <ValidationForm  onSubmit={handleSubmit} id="form-test" ref={formRefs}>
                        {form.field.map(function (fields, index) {
                            return (
                                <div className="row form-group mb-1" key={index}>
                                    <div className="col-lg-4 col-sm-4 col-md-4">{fields.label}</div>
                                    <div className="col-lg-8 col-sm-8 col-md-8">
                                        <TextInput
                                            type={fields.type}
                                            className="form-control"
                                            name={fields.name}
                                            autoComplete="off"
                                            required
                                            {...(form.formType == 'add' && fields.name == 'brand_code' ? {minLength : "4"} : {})}
                                        />
                                    </div>
                                </div>
                            );
                        })}
                        <button type="submit" className="btn btn-danger">
                            Save
                        </button>
                        <button type="button" className="btn btn-warning" onClick={() => resetForm()}>
                            Reset Form
                        </button>
                    </ValidationForm>
                </div>
            </div>
        </div>
    );
}

export default TestForm;

当从父组件接收到的道具没有改变时,上面的代码可以正常工作,并且当我尝试通过 onClick 触发按钮重置表单时,它也可以正常工作。但是当我想在父组件的 props 发生变化时重置表单时,会产生如下错误:

警告:在现有状态转换期间无法更新(例如在render 内)。渲染方法应该是 props 和 state 的纯函数

谁能帮我解决这个问题?事先非常感谢。

【问题讨论】:

    标签: javascript reactjs react-hooks use-ref


    【解决方案1】:

    尝试将useCompare检查移动到副作用:

    useEffect( () => {
        if ( !useCompare(form) ) {
            resetForm()
        }
    }, [useCompare, form, resetForm] )
    

    您可能必须将resetForm 包装在useCallback 挂钩中。

    useEffect 将在每次form 更改时运行,将其放置在此处应该可以防止“渲染期间更新”问题。

    【讨论】:

    • @Nick ..没有正确理解。请详细说明为什么需要在这里使用 useEffect()
    • 最初,在渲染方法中,他试图重置作为道具传入的表单。这将在渲染完成之前修改道具。正确的方法是让渲染完成,然后在必要时重置表单(在 useEffect 挂钩中。)
    猜你喜欢
    • 1970-01-01
    • 2019-11-26
    • 2020-01-04
    • 2019-11-06
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    相关资源
    最近更新 更多