React父组件props变化重置表单报Cannot update during state transition错误如何解决
问题原因
你将resetForm()调用直接写在了组件渲染的顶层逻辑中,当父组件传入的form prop变化触发组件重渲染时,渲染流程尚未完成就执行了resetValidationState方法,而这个方法会修改ValidationForm的内部状态,违反了React「渲染函数必须是纯函数、禁止在渲染过程中修改状态」的规则,因此抛出了警告。
解决方案
使用useEffect钩子监听form prop的变化,将重置逻辑放到渲染完成后的副作用阶段执行即可,核心修改点如下:
- 从React中导入
useEffect - 删除顶层的
if ( !useCompare(form) ) { resetForm() }逻辑 - 新增副作用监听逻辑:
useEffect(() => { // form prop发生变化时执行重置 if (!useCompare(form)) { resetForm() } }, [form])
修改后的完整组件代码如下:
import React, { useRef, useEffect } 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) } // 新增副作用逻辑,监听form变化执行重置 useEffect(() => { if (!useCompare(form)) { resetForm() } }, [form]) 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"> 保存 </button> <button type="button" className="btn btn-warning" onClick={() => resetForm()}> 重置表单 </button> </ValidationForm> </div> </div> </div> ); } export default TestForm;
注意:如果你的
useCompare是深比较逻辑,该方案可以正常运行;如果仅做浅比较,当form是引用类型且只修改内部属性时,你可以根据需要调整useEffect的依赖项,或者改用深比较逻辑。
内容的提问来源于stack exchange,提问作者snouck
相关产品推荐
相关产品推荐

