React如何仅用单个函数实现父子组件间对象传递更新表单数据
解决方案
核心逻辑是让updateData接收字段键值对对象作为入参,父组件直接用入参合并更新全局表单状态,仅需这一个函数即可实现全字段更新。
第一步:修改父组件 UserFormular 的 updateData 逻辑
import React, {useState} from 'react' import PersonalData from './PersonalData' export default function UserFormular() { const initialData={ name:'Johnny', lastName:'Bravo', email:'email@email.com' } const [data,setData] = useState(initialData) // 修改:接收要更新的字段对象作为参数 function updateData(newField){ setData(prevState => ({ ...prevState, ...newField // 合并新的字段键值对 })) } return( <PersonalData updateData={updateData} // 可选:把表单值传给子组件做受控组件,避免子组件单独维护状态 formData={data} /> ) }
第二步:修改子组件 PersonalData 的调用逻辑
你需要给每个输入框加上和父级state键名对应的name属性,触发更新时把当前字段的键值对传给updateData即可:
import React, {useContext} from 'react' // 可以删掉子组件单独的三个 useState,避免重复维护状态 import {MyContext} from '../utils/CustomContext' import Header from './Header' // MATERIAL UI import TextField from '@mui/material/TextField'; export default function PersonalData({updateData, formData, nextPage }) { const darkMode = useContext(MyContext) const myStyle={ myButtonContainer:{ marginTop:"100px", display:"flex", flexDirection:"column", justifyContent:"center", alignItems:"center" }, myButton:{ backgroundColor:darkMode ? "#888" : "#111", } } function handleData(e){ // 从输入框的name属性取字段名,value取输入值 const fieldName = e.target.name const fieldValue = e.target.value // 把键值对传给父级的更新函数 updateData({ [fieldName]: fieldValue }) } return ( <> <div style={myStyle.myButtonContainer}> <TextField helperText="Please enter your name" label="Name" name="name" // 新增:和父级state的键名对应 value={formData.name} // 绑定父级的表单值,做成受控组件 onChange={handleData} sx={{m:6, mb:2}} /> <TextField helperText="Please enter your last name" label="Last name" name="lastName" // 新增:和父级state的键名对应 value={formData.lastName} onChange={handleData} sx={{m:2}} /> <TextField helperText="Please enter your email" label="email" name="email" // 新增:和父级state的键名对应 value={formData.email} onChange={handleData} sx={{m:2}} /> </div> </> ) }
优化说明
- 去掉了子组件内单独维护的
name/lastName/email三个状态,直接复用父级的表单数据,避免出现状态不同步的问题 - 后续如果新增字段,只需要在父级的
initialData里加对应键,子组件加对应name属性的输入框即可,不需要修改updateData函数,也不需要新增props
内容的提问来源于stack exchange,提问作者Kamil Zawiślak
相关产品推荐
相关产品推荐

