如何将React Query返回的data作为useState初始值并支持编辑?
优雅实现useQuery数据作为useState初始值的方案
问题分析
原代码中useState的初始值仅在组件挂载时执行一次,此时useQuery的异步请求尚未完成,data为undefined,导致name初始值为空。即便后续请求完成,useState也不会自动更新,因此需要更合理的方式同步数据。
简洁解决方案
方案1:监听data变化同步state(通用场景)
直接监听data的变化,当数据返回后自动更新useState,相比监听isLoading更精准,能覆盖数据重新获取的场景:
import { useQuery } from '@tanstack/react-query'; import { useState, useEffect } from 'react'; const YourComponent = ({ nameId }) => { const { data, isLoading } = useQuery({ queryKey: ["name", nameId], queryFn: async () => { const consulta = await getFetch(`${NAME_URI}/${nameId}`); return consulta as NameType | undefined; }, }); // 初始值用可选链避免报错,默认空字符串 const [name, setName] = useState(data?.name || ''); // 当data返回或更新时,同步到state useEffect(() => { if (data?.name) { setName(data.name); } }, [data]); return ( <div> {isLoading ? <p>加载中...</p> : <p>{JSON.stringify(data.name)}</p>} <p>{name}</p> {/* 编辑控件示例 */} <input value={name} onChange={(e) => setName(e.target.value)} placeholder="编辑名称" /> <button onClick={() => mutateAsync({ id: nameId, name })}>保存修改</button> </div> ); };
方案2:仅首次加载同步state(编辑场景)
如果编辑过程中不希望重新请求的data覆盖用户已修改的内容,可以用useRef标记初始化状态,仅在首次加载时同步:
import { useQuery } from '@tanstack/react-query'; import { useState, useEffect, useRef } from 'react'; const YourComponent = ({ nameId }) => { const { data, isLoading } = useQuery({ queryKey: ["name", nameId], queryFn: async () => { const consulta = await getFetch(`${NAME_URI}/${nameId}`); return consulta as NameType | undefined; }, }); const [name, setName] = useState(''); const isInitialized = useRef(false); useEffect(() => { // 仅首次获取到数据时初始化state if (data?.name && !isInitialized.current) { setName(data.name); isInitialized.current = true; } }, [data]); return ( <div> {isLoading ? <p>加载中...</p> : <p>{JSON.stringify(data.name)}</p>} <p>{name}</p> <input value={name} onChange={(e) => setName(e.target.value)} placeholder="编辑名称" /> <button onClick={() => mutateAsync({ id: nameId, name })}>保存修改</button> </div> ); };
关键优化点
- 用
data?.name可选链操作符,避免初始阶段data为undefined导致的报错 - 监听
data而非isLoading,精准响应数据状态变化,逻辑更可靠 - 编辑场景下通过
useRef控制仅初始化一次,避免用户输入被覆盖
内容的提问来源于stack exchange,提问作者Miguel Angel Marroquin Jordan
相关产品推荐
相关产品推荐

