React Redux 页面刷新后useEffect未成功设置表单数据问题
问题修复方案
根因分析
- 闭包陷阱:你写的空依赖useEffect中捕获的
user永远是组件首次挂载时的初始值(也就是undefined),即便dispatch(loadOrCreateUser())异步执行完成更新了Redux中的user状态,当前useEffect作用域内的user也不会同步更新,因此给表单赋值时读取的是空值。 - 钩子使用不规范:直接给useEffect的回调函数加
async修饰符会返回Promise,不符合useEffect要求回调仅返回清理函数或无返回值的规则,存在内存泄漏隐患。 - 缺少状态监听:没有将useSelector获取的
user加入依赖项,Redux中user更新后无法触发表单重新赋值的逻辑。
修复后的核心代码
修改Profile.js中的useEffect部分即可:
import React from 'react' import { Link, Redirect } from 'react-router-dom' import { useState, useEffect } from 'react' import { useSelector, useDispatch } from 'react-redux' import { loadOrCreateUser, updateUser } from '../../state/action-creators/authActions' const Profile = () => { const dispatch = useDispatch(); const user = useSelector(state => state.auth.user); // 顺便修正字段拼写错误 filedCheck -> fieldCheck const [fieldCheck, setFieldCheck] = useState(false); const [formData, setFormData] = useState({ username: "", email: "", first_name: "", last_name: "", about: "", password: "" }); const {username, email, first_name, last_name, about, password} = formData; useEffect(() => { formData.password !== '' ? setFieldCheck(false) : setFieldCheck(true); }, [formData.password]) // 单独拆分useEffect执行用户信息拉取逻辑 useEffect(() => { const fetchUser = async () => { await dispatch(loadOrCreateUser()); } fetchUser(); }, [dispatch]) // 新增useEffect监听Redux中user的变化,同步更新表单 useEffect(() => { // 仅当user存在时才赋值,避免读取undefined属性报错 if (user) { setFormData(prev => ({ ...prev, username: user.username, email: user.email, first_name: user.first_name, last_name: user.last_name, about: user.about })); } }, [user]) const onChange = e => setFormData({ ...formData, [e.target.name]: e.target.value }); const onSubmit = e => { e.preventDefault(); const data = { username, email, first_name, last_name, about, password }; dispatch(updateUser(data)); } return ( // Form inputs... ) } export default Profile
补充说明
- 拆分两个useEffect的目的是逻辑解耦,拉取用户信息和监听用户状态更新分开处理,后续如果有其他地方修改了Redux中的user状态,表单也能自动同步最新值。
setFormData使用函数式更新写法,可直接拿到最新的表单状态,避免闭包导致的旧值覆盖问题。
内容的提问来源于stack exchange,提问作者Luka Reeson
相关产品推荐
相关产品推荐

