React 18子组件使用setState更新对象属性失效问题排查
问题分析与解决
你的问题核心在于对React状态更新的异步特性理解不足,以及后续操作时机错误,具体问题和修复方案如下:
1. setState是异步操作,不能立刻获取更新后的值
你在调用parentInfo.setUserData后立刻console.log(parentInfo),此时React还没完成状态更新,parentInfo.userData还是旧值,所以看不到更新后的code。同理,直接在这个位置执行localStorage.setItem也只能存储旧数据。
2. 正确获取更新后状态的方式
要在状态更新后执行后续操作(比如存入localStorage),可以在子组件中用useEffect监听parentInfo.userData的变化:
import { useEffect } from 'react'; function Child({parentInfo}) { const client = axios.create({ baseURL: "http://localhost:7171/api/" }); // 监听userData变化,更新后执行存储操作 useEffect(() => { if (parentInfo.userData.code) { localStorage.setItem('key', JSON.stringify(parentInfo.userData)); console.log(parentInfo.userData); // 这里能拿到更新后的数据 } }, [parentInfo.userData]); // 依赖项设为userData,变化时触发 const handleSubmit = e => { e.preventDefault(); client.post('public/someAPI',someData).then((response) => { if(response.status === 200){ parentInfo.setUserData(prevData => ({ ...prevData, code: response.data.code })) }); } return( <header className="form-header"> {/* 原代码直接显示对象会输出[object Object],改成显示具体属性 */} <h2>当前Code: {parentInfo.userData.code}</h2> </header> <form className="form flex-col" onSubmit={handleSubmit}> <button type="submit" >Submit</button> </form> ) } export default Child;
3. 验证状态是否真的更新
你之前觉得code始终为空,很大概率是因为错误的时机去查看数据,而非setState未生效。修改渲染部分为显示parentInfo.userData.code后,当接口返回成功,组件会重新渲染,你就能在页面上看到更新后的code值。
另外,你的setState写法是正确的(使用函数式更新,基于prevData展开),这部分无需修改。
内容的提问来源于stack exchange,提问作者ksernow
相关产品推荐
相关产品推荐

