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

Posted

技术标签:

【中文标题】ReactJS:在现有状态转换期间无法更新(例如在 `render` 中)。渲染方法应该是 props 和 state 的纯函数【英文标题】:ReactJS: Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and 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 的纯函数

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

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

@Nick ..没有正确理解。请详细说明为什么需要在这里使用 useEffect() 最初,在渲染方法中,他试图重置作为道具传入的表单。这将在渲染完成之前修改道具。正确的方法是让渲染完成,然后在必要时重置表单(在 useEffect 挂钩中。)

以上是关于ReactJS:在现有状态转换期间无法更新(例如在 `render` 中)。渲染方法应该是 props 和 state 的纯函数的主要内容,如果未能解决你的问题,请参考以下文章

反应JS |在现有状态转换期间无法更新

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

在无状态组件中的现有状态转换期间无法更新

在现有状态转换期间无法更新

如何通过构建现有状态来更新 reactjs 应用程序的状态?

相机不显示,状态转换问题,反应原生