React中useNavigate传状态后,Job组件无法更新本地状态
问题:复用Job页面时无法从location state更新表单状态
我有一个用于创建新作业实例的Job页面,页面包含表单字段;已创建的作业会在另一页面以JobCard组件展示摘要信息,这部分功能正常。
现在尝试从JobCard组件跳转至Job页面以展示作业完整信息:在JobCard的onClick函数中从后端拉取作业详情,通过useNavigate的state参数传递给Job页面,在Job页面使用useLocation读取这些参数。能正常接收参数,但无法将其设置到Job组件的本地状态中,希望复用创建作业的Job页面而非新建页面。
JobCard的onClick代码
const handleJobDetails = async (e) => { try { const jobFetchDetails = await jobServices.getJobDetails(job.id); // compose jobs payload const jobProps = { vehicles: [], vehicle: jobFetchDetails.cust_info.vehicle, model: jobFetchDetails.cust_info.model, mobile: jobFetchDetails.cust_info.mobile, ... }; navigate("/job", { state: { jobProps: jobProps } }); } catch (error) { handleError(error); } };
Job组件代码
const initialValues = { vehicles: [], vehicle: "", model: "", mobile: "", email: "", ... }; // used to reset form export default function Job() { const navigate = useNavigate(); const location = useLocation(); const { values, setvalues, } = useForm(initialValues); // custom hook useEffect(() => { const fetchParts = async () => { const partList = await partServices.fetchParts(); setvalues((values)=>({ ...values, parts: partList })); }; fetchParts().catch((error) => handleError(error)); // Setting state from JobCard if available const { state } = location; const { jobProps } = state || {}; if (jobProps && jobProps.job_id) { // job props received // set state from jobProps setvalues((values) => ({ ...values, jobProps })); } navigate(".", {replace: true}); // reset location state }, [navigate]); }
控制台显示jobProps已正确传递,但Job组件状态未更新,页面也未显示对应值。
问题原因及解决方案
1. useEffect依赖数组缺失
当前useEffect的依赖数组只有navigate,但逻辑中依赖了location对象。当从JobCard跳转过来时,location发生变化,但useEffect不会重新触发,导致状态更新逻辑不会执行。
2. 状态合并方式错误
你当前的代码是把jobProps作为嵌套对象赋值给values,但表单的初始值是平级结构(如vehicle、model等),这样会导致表单字段无法读取到嵌套在jobProps里的值。
3. 导航重置state的时机不当
在useEffect中直接调用navigate(".", {replace: true})会触发组件重新渲染,可能在状态更新完成前就重置了location,甚至覆盖刚设置的状态。
修正后的Job组件useEffect代码
useEffect(() => { const fetchParts = async () => { const partList = await partServices.fetchParts(); setvalues((values)=>({ ...values, parts: partList })); }; fetchParts().catch((error) => handleError(error)); // Setting state from JobCard if available const { state } = location; const { jobProps } = state || {}; if (jobProps && jobProps.job_id) { // 展开jobProps的平级字段,合并到现有values中 setvalues((prevValues) => ({ ...prevValues, ...jobProps })); // 处理完状态后再重置location state navigate(".", {replace: true}); } }, [navigate, location]); // 将location加入依赖数组
额外注意事项
- 确认自定义
useForm的setvalues支持函数式更新:确保该方法能正确接收前一次状态并返回新状态,否则状态合并会失败。 - 校验
jobProps的字段匹配:确保jobProps中的键名和initialValues完全一致,比如mobile、model等字段名必须对应,否则无法正确映射到表单。
内容的提问来源于stack exchange,提问作者Yusuf Mirza
相关产品推荐
相关产品推荐

