Next.js中React状态通过Props初始化后不随新Props更新的问题
问题:React Query加载完成后组件本地爱好列表状态未更新
场景复现
在Next.js项目中使用TanStack React Query实现骨架加载,数据加载完成后,name字段正常更新,但hobbies本地状态始终保持初始的空数组,只有页面跳转后返回才会加载新数据。
父组件加载逻辑代码:
if (isPending) { return <MyComponent name="Loading...." hobbies={[]} /> } return <MyComponent name={data.name} hobbies={data.hobbies} />
子组件MyComponent代码:
function onSubmit() { /* 提交到服务器的逻辑 */ } function MyComponent(props) { const [hobbies, setHobbies] = useState(props.hobbies); return ( <form> <h1>{props.name}</h1> <MyList hobbies={hobbies} /> <div> <input /> <button type="button" onClick={() => {}}>add</button> </div> <button onClick={onSubmit}>submit</button> </form> ) }
问题原因
useState的初始值仅在组件首次挂载时生效,当父组件传递的props.hobbies更新时,子组件的本地hobbies状态不会自动同步——useState本身不会监听props的变化。
解决方案
通过useEffect监听props.hobbies的变化,当props更新时同步更新本地状态,同时可根据业务需求避免覆盖用户已做的本地修改。
修改后的MyComponent代码:
function onSubmit() { /* 提交到服务器的逻辑 */ } function MyComponent(props) { const [hobbies, setHobbies] = useState(props.hobbies); // 标记是否有用户本地修改 const [hasLocalChanges, setHasLocalChanges] = useState(false); // 仅在无本地修改时,同步服务器返回的新数据 useEffect(() => { if (!hasLocalChanges) { setHobbies(props.hobbies); } }, [props.hobbies, hasLocalChanges]); // 处理添加爱好的逻辑,同时标记已有本地修改 const handleAddHobby = () => { setHobbies(prev => [...prev, '新爱好']); setHasLocalChanges(true); } // 提交后重置本地修改标记 const handleSubmit = () => { onSubmit(hobbies); setHasLocalChanges(false); } return ( <form> <h1>{props.name}</h1> <MyList hobbies={hobbies} /> <div> <input /> <button type="button" onClick={handleAddHobby}>add</button> </div> <button onClick={handleSubmit}>submit</button> </form> ) }
简化版(无需区分本地修改场景)
如果业务上允许服务器数据覆盖所有本地未提交的修改,可直接去掉本地修改标记逻辑:
function MyComponent(props) { const [hobbies, setHobbies] = useState(props.hobbies); useEffect(() => { setHobbies(props.hobbies); }, [props.hobbies]); // 其他逻辑保持不变 }
内容的提问来源于stack exchange,提问作者randomuser5767124
相关产品推荐
相关产品推荐

