子组件更新父组件state后父组件未重新渲染问题
问题修复方案
1. 先改最致命的拼写错误
子组件接收的props写成了setUserDate,但父组件传的是setUserData——差了一个字母!这直接导致子组件里根本拿不到更新父组件状态的方法,自然改完也没反应。
子组件代码修改:
// 把参数里的setUserDate改成setUserData function UpdateUser({ userData, setUserData }) { // 后面所有用到setUserDate的地方,全换成setUserData }
2. 去掉父组件useEffect里多余的依赖
父组件的useEffect把userData加进了依赖数组,这会导致每次userData变化就重新发请求拿用户列表,完全没必要,还可能搞出额外的渲染问题。
父组件useEffect修改:
useEffect(() => { const getUsers = async () => { // 原来的请求逻辑不变 }; getUsers(); }, [dispatch, navigate]); // 删掉依赖里的userData
3. 确保userData有真实的初始数据
现在父组件的userData一开始是空对象emptyUser,要是没在其他地方(比如选用户的时候)给它赋值,表单改的是空数据,当然看不到变化。得加个用户选择的逻辑,比如点击列表里的用户,把数据塞给userData:
// 举个例子,点击用户项触发这个函数 const pickUser = (selectedUser) => { setUserData(selectedUser); };
4. 用函数式更新避免闭包问题
子组件里更新状态的时候,最好用函数式写法,防止因为闭包拿不到最新的userData:
比如onInputChange改成这样:
const onInputChange = (e, variable) => { const val = e.target?.value || ""; // 用prev取最新的状态 setUserData(prev => ({ ...prev, [variable]: val })); setDisableBtn(false); };
onSelectFile同理改一下:
const onSelectFile = (e) => { if (!e.target.files?.length) { setUserData(prev => ({ ...prev, image: undefined })); return; } setUserData(prev => ({ ...prev, image: e.target.files[0] })); setDisableBtn(false); };
5. 编辑成功后更新父组件的用户列表
现在编辑完用户,父组件的users列表还是旧数据,得更新一下。可以在子组件编辑成功后,让父组件重新拉取用户列表,或者直接修改users数组:
比如在子组件的editUser里,成功后加个逻辑:
// 假设编辑成功的判断是data.status === 200 if (data.status === 200) { console.log("success"); // 这里可以调用父组件传过来的更新列表的方法,比如父组件传个refreshUsers // refreshUsers(); // 或者直接重新发请求(但推荐让父组件处理) }
内容的提问来源于stack exchange,提问作者Aasem Shoshari
相关产品推荐
相关产品推荐

