React useRef存储query值为空但orderBy取值正常问题排查
问题根因
你的useRef用法完全错误,同时对useRef的更新机制存在误解:
useRef(initialValue)的入参仅在组件首次挂载渲染时会被用作ref的初始值,后续所有重渲染过程中,哪怕你给useRef传入新的值,React也会直接忽略该入参,返回首次创建的ref对象,其current属性不会自动更新为新传入的值。- 你写的
const query = useRef(_query).current,本质是每次渲染都调用useRef拿到存着初始值的ref,再取它的current,拿到的永远是组件第一次渲染时传入的_query初始值。
orderBy取值正常只是巧合:你调用Hook时传入的_orderBy从组件首次渲染开始就是正确的['pickedUpAt', 'desc']数组,后续重渲染从来没变更过初始值,所以哪怕你用错误写法拿值,结果看起来也是对的。
而_query在组件首次渲染时传入的初始值就是空字符串,后续父组件异步计算出查询条件、传入新的三元素数组时,ref的current还是存着第一次的空字符串,就出现了你日志里看到的“_query是正确数组,但取ref值是空串”的现象。
修复方案
如果要实现“保留参数最新值、同时避免数组类型参数引用变化触发useEffect无限循环”的需求,正确写法如下:
export const useCollection = (collection, _query, _orderBy) => { const [documents, setDocuments] = useState(null); const [error, setError] = useState(null); // 初始化ref const queryRef = useRef(_query); const orderByRef = useRef(_orderBy); // 每次渲染同步最新参数到ref,该操作不会触发组件重渲染 queryRef.current = _query; orderByRef.current = _orderBy; useEffect(() => { // effect内部读取ref的current,永远能拿到最新参数值 const query = queryRef.current; const orderBy = orderByRef.current; // 此处编写你的数据拉取逻辑 // 依赖数组仅放入不会频繁变更引用的基础类型值(比如collection)即可,避免无限循环 }, [collection]) if (collection === "items") { console.log("query:", queryRef.current); console.log(queryRef.current === ""); console.log("_query:", _query); console.log("orderBy:", orderByRef.current); console.log("_orderBy:", _orderBy); } return { documents, error } }
内容的提问来源于stack exchange,提问作者sketchrandal900
相关产品推荐
相关产品推荐

