提交子表单后重新渲染父组件以重置bs-stepper向导
解决bs-stepper表单提交后重置向导的问题
我使用bs-stepper实现长表单向导,表单数据存储在父组件state中。提交表单后,虽然已将父组件state重置为初始值,但向导仍停留在最后一步,输入框旧内容也未清空。需要实现提交后将向导重置回第一步,同时清空所有输入内容。
原父组件代码:
import Step1 from './step1' import Step2 from './step2' import StepLast from './steplast' const Parent = () => { const initialState = { name: '', lastname: '', email: '', // and so on } const [data, setData] = useState(initialState) const steps = [ { id: 'step1', title: 'Step One', content: <Step1 data={data}, setData={setData} />}, { id: 'step2', title: 'Step Two', content: <Step2 data={data}, setData={setData} />}, { id: 'steplast', title: 'Step Last', content: <StepLast data={data}, setData={setData} initialState={initialState} />} ] return ( <> <Wizard steps={steps} /> </> ) } export default Parent
原Step1组件:
const Step1 = ({data, setData}) => { const nextStep = (e) => { e.preventDefault() // go to next step } return ( <> <Form> <Input type='text' onInput={e => setData({...data, name: e.target.value})} /> <Button type='button' onClick={e => nextStep(e)} /> </Form> </> ) }
原StepLast组件:
const StepLast = ({data, setData, initialState}) => { const saveData = () => { axios.post('api/address', data) .then(response => { console.log(response) // this is ok setData(initialState) // this is resetting state // HERE I NEED TO RESTART THE WIZARD }) .catch(error => { console.error('error', error) } } return ( <> <Form onSubmit={handleSubmit(saveData)}> <Input type='email' onInput={e => setData({...data, email: e.target.value})} /> <Button type='submit' /> </Form> </> ) }
解决方案
1. 父组件新增状态控制与重置逻辑
在父组件中添加当前步骤跟踪状态、stepper实例引用,并定义重置方法传递给子组件:
import Step1 from './step1' import Step2 from './step2' import StepLast from './steplast' import { useState, useRef } from 'react' const Parent = () => { const initialState = { name: '', lastname: '', email: '', // 其他字段 } const [data, setData] = useState(initialState) const [currentStep, setCurrentStep] = useState(1) // 跟踪当前步骤 const stepperRef = useRef(null) // 获取bs-stepper实例 // 重置向导与表单数据 const resetStepper = () => { setData(initialState) setCurrentStep(1) // 调用bs-stepper实例方法跳转到第一步 if (stepperRef.current) { stepperRef.current.to(1) } } const steps = [ { id: 'step1', title: 'Step One', content: <Step1 key={`step1-${data.name}`} // 动态key确保data变化时重新渲染组件 data={data} setData={setData} setCurrentStep={setCurrentStep} /> }, { id: 'step2', title: 'Step Two', content: <Step2 key={`step2-${data.lastname}`} data={data} setData={setData} setCurrentStep={setCurrentStep} /> }, { id: 'steplast', title: 'Step Last', content: <StepLast key={`steplast-${data.email}`} data={data} setData={setData} resetStepper={resetStepper} // 传递重置方法 /> } ] return ( <> <Wizard ref={stepperRef} steps={steps} currentStep={currentStep} /> </> ) } export default Parent
2. 调整StepLast组件调用重置方法
提交成功后直接调用父组件的重置方法:
import axios from 'axios' import { handleSubmit } from 'react-hook-form' const StepLast = ({data, setData, resetStepper}) => { const saveData = () => { axios.post('api/address', data) .then(response => { console.log(response) resetStepper() // 触发重置 }) .catch(error => { console.error('error', error) }) } return ( <> <Form onSubmit={handleSubmit(saveData)}> <Input type='email' value={data.email} // 绑定value确保与state同步 onInput={e => setData({...data, email: e.target.value})} /> <Button type='submit' /> </Form> </> ) }
3. 完善步骤组件的输入框绑定
给所有步骤的输入框添加value属性,确保state变化时输入框内容同步更新:
const Step1 = ({data, setData, setCurrentStep}) => { const nextStep = (e) => { e.preventDefault() setCurrentStep(2) // 更新步骤 } return ( <> <Form> <Input type='text' value={data.name} // 绑定value onInput={e => setData({...data, name: e.target.value})} /> <Button type='button' onClick={nextStep} /> </Form> </> ) }
核心要点
- 绑定value属性:这是输入框内容与state同步的关键,之前的代码缺少此绑定导致state重置后输入框未更新。
- 控制步骤状态:通过父组件的
currentStep管理向导进度,提交后重置为第一步。 - 操作stepper实例:利用ref调用bs-stepper的
to()方法,强制向导UI跳转到第一步。 - 动态key:给步骤组件添加基于data的动态key,确保data重置时组件重新挂载,彻底清空输入内容。
内容的提问来源于stack exchange,提问作者leandronn
相关产品推荐
相关产品推荐

