如何从React RTK Query实时更新状态值?
如何从React RTK Query实时更新状态值?
嘿,我完全懂你碰到的这个问题——用RTK Query拉取后端数据初始化表单状态后,后续接口返回新数据时,本地的state却没跟着更新,只会停留在第一次加载的值,甚至得刷新页面才会变,对吧?
其实问题出在useState的特性上:它的初始值只会在组件首次渲染时生效一次,哪怕后续post变量变化了,useState(post?.name)也不会重新执行来更新状态。要解决这个,我们需要主动监听RTK Query返回的data变化,然后同步更新本地state。
基础解决方案:用useEffect监听数据变化
最简单的方式就是加个useEffect,当post更新时,手动把最新的post.name同步到postName状态里:
export function Posts() { const { data: post, isFetching, isLoading } = useGetPostQuery(); const [postName, setPostName] = useState(post?.name); // 监听post的变化,实时同步到本地状态 useEffect(() => { if (post?.name) { setPostName(post.name); } }, [post]); // 依赖项设为post,post更新时触发 if (isLoading) return <>Loading</>; if (!post) return <>Missing posts!</>; return ( <div> <input value={postName} onChange={(event) => setPostName(event.target.value)} /> </div> ); }
这样不管是第一次加载数据,还是后续接口返回了新的内容,postName都会跟着更新,表单也会实时反映最新的后端数据。
进阶优化:避免覆盖用户输入
如果担心后端数据更新时,会覆盖用户已经编辑过的表单内容,我们可以加个标记状态,只有当用户还没编辑过表单时,才同步后端的新数据:
export function Posts() { const { data: post, isFetching, isLoading } = useGetPostQuery(); const [postName, setPostName] = useState(post?.name); const [isUserEdited, setIsUserEdited] = useState(false); // 仅在用户未编辑且post更新时同步数据 useEffect(() => { if (!isUserEdited && post?.name) { setPostName(post.name); } }, [post, isUserEdited]); if (isLoading) return <>Loading</>; if (!post) return <>Missing posts!</>; return ( <div> <input value={postName} onChange={(event) => { setPostName(event.target.value); setIsUserEdited(true); // 用户开始编辑后,标记为已编辑状态 }} /> </div> ); }
这个版本里,用户一旦开始输入,isUserEdited就会变成true,之后哪怕后端数据更新,也不会再覆盖用户的输入啦,兼顾了数据同步和用户体验。
内容来源于stack exchange
相关产品推荐
相关产品推荐

