230 - 《React Query 笔记:上》

发布于 2022年12月13日

要开始做请求方案的调研,第一个深入看的是 React Query(下面简称为 RQ)。本文是 Practical React Query | TkDodo’s blog 系列文章的阅读笔记。

0、为啥很多人会认为 apollo 会取代 redux?apollo 是请求方案,而 redux 是全局状态库,看起来八竿子打不着,但如果我们能在客户端通过缓存的方式访问服务端的数据,那对于 80% 的应用来说,剩下需要处理的客户端状态其实很少。所以,apollo 会取代 redux 吗?It Depends。而 apollo 是处理 graphql 的,RQ 则把 apollo 的很多功能带到了 restful 的 api 场景(且不限于此)。

1、一些文档外的使用技巧。1)默认值的选择很好,但对于新手用户也会有时不时的措手不及,需要理解他们,2)使用 React Query DevTools,会告诉你缓存的数据状态,同时也要结合 Chrome DevTool 的网络面板,因为开发模式请求通常比较快,3)把 query key 当 useEffect 的依赖数组使用,两者非常相似,4)通过传入 initialData 可以让切换状态时先用缓存中的数据做预填充,提升用户体验,比如 todo app 的 filter 从全部切换到完成时的场景,5)保持服务端和客户端状态分离,useQuery() 得到的数据不要存本地 copy,以避免拿到老数据,6)enable 配置项非常强大,可以做很多事,比如依赖另一个查询的数据、modal 打开时关闭数据轮询、等待用户输入时禁用、用户输入信息后禁用默认数据的查询等,7)不要尝试通过 queryClient.setQueryData 修改 query cache 使他成为本地状态管理器,因为每次后台重新获取都可能覆盖他们,8)把 useQuery 包起来用会有额外好处,比如 ui 和逻辑分离等。

2、如果后端没有返回期望的数据格式,那就需要做格式化了。这时有多个选择,1)后端转,缺点是不一定能实现,2)queryFn 里转,缺点是每次 fetch 时需要跑一遍,同时如果你有一个不能自由修改的 service 层可能行不通(不能通过 openapi 生成的),3)render 函数中转,缺点是语法复杂,需借助 useMemo 提升性能,同时数据可能 undefined,4)用 select option 转,没啥明显缺点。所以,相对来说,方案 4 会更好,最佳优化(调用次数最少)、同时允许部分订阅。

3、RQ 内置了一些渲染优化的能力。1)notifyOnChangeProps 配置,从版本 4 起默认开启 track 模式,跟踪你使用了哪些 props,然后只在这些 props 变更后做 notify,可选配置是 all 或 String 数组,选 String 数组 要注意 props 的同步手动更新,避免出现该渲染没渲染然后使用过期数据的问题,2)RQ 做了结构共享,比如 [{id:1,text:1},{id:2,text:2}],如果更新数据后只变更了 id 1,那通过 useItems(/*id*/2) 拿的数据会保持引用一致性,不会 notify 更新,详见 replaceEqualDeep 的测试

4、RQ 有 3 种状态,success、error 和 loading(idle 在版本 4 里去掉了),以及另一个维度的 isFetching。应该是怎样的状态检测顺序?通常大家会写 loading、error、data(即 success

内容预览已结束

此内容需要会员权限。请先登录以查看完整内容。