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

ReactJS:无法在现有状态转换期间更新(例如在渲染中)。渲染方法应该是道具和状态的纯函数

云长恨
2023-03-14

你好,我是ReactJS的新手,我正在使用库react-bootstrap4-form-validation来验证我的表单。文档中有用于重置表单验证的函数。文档中有使用触发按钮onClick重置表单验证的示例,如下所示。对于一个条件,我需要重置验证,但不是在触发按钮onClick时,而是在父组件的道具更改时。由于这些需要,我还创建了一个函数(useCompare),用于比较从父组件接收的道具。

简而言之,当从父组件接收到的道具发生更改时,我想重置我的表单,代码如下所示。

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触发器按钮重置表单时,也可以正常工作。但是,当我想在父组件的道具更改时重置表单时,它会生成如下错误:

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

有人能帮我解决这个问题吗?我事先非常感激。


共有1个答案

糜雪峰
2023-03-14

尝试移动useCompare检查是否有副作用:

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

您可能需要将resetForm包装在useCallback钩子中。

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

 类似资料: