看了下很多人推荐用这个,但是官网文档也太简单了,而且也没有 api 参考,比如那个 isvalidating ,官网一句话就没了,看了下示例,这个是指 mutate 以后加载的加载中状态吗?
另外还搜了下如果想实现根据 id list 拿数据,得手动实现一个接受 id list ,返回 promise 的 fetcher ?
那 id list 本身也是一个请求拿到的呢,如何实现先刷新 id list ,再刷新 id list 对应的数据?
另外 react query 看起来功能多不少,会不会更好用些?
1
TWorldIsNButThis OP const fetchId = async () => {
await new Promise((res) => setTimeout(res, 1000)) const millis = new Date().getMilliseconds().toString() return millis .substring(millis.length - 4) .split('') .map(Number) } const fetchData = async (ids: number[]) => { await new Promise((res) => setTimeout(res, 1000)) return await Promise.all(ids.map((id) => new Promise((res) => res(`data-${id}`)))) } const useData = () => { const { data: ids, isValidating: updateId, mutate: mutateId } = useSwr('/api/ids', fetchId) const { data, mutate: mutateData, isValidating: updateData, } = useSwr(ids && 'data', async () => { return await fetchData((await mutateId()) || []) }) return { ids, data, mutateData, mutateId, updateData, updateId, } } 好像找到一个解决方案,在 dependent query 里 mutate id ,根据返回的 id 再去请求,由于 swr 在短时间内多次调用只会发一次请求,所以最终也就发两次请求?但是不知道这算不算 anti-pattern ? |
2
TWorldIsNButThis OP 但是这样写第一次渲染的时候一定会请求两次 id ,有什么方法优化吗
另外如果用 react query 实现相同的功能会不会简单些? |
3
HeStudy 2022-03-13 13:55:20 +08:00 via Android
推荐 ahooks 里的 useRequest
|
4
TWorldIsNButThis OP const useData = () => {
const { data: ids, isValidating: updateId, mutate: mutateId, } = useSwr('/api/ids', fetchId, { onSuccess: async () => { await mutateData() }, }) const { data, mutate: mutateData, isValidating: updateData } = useSwr(() => ids, fetchData) return { ids, data, mutateData, mutateId, updateData, updateId, } } 又换了个写法,现在请求次数就是 id 和 data 各一次了 感觉好像 dependent query 没必要保持 key 不变,但是在 id 的 onSucess 里刷新它的 dependent query 好像也有点怪。。 |
5
TWorldIsNButThis OP @HeStudy useRequest 的话是用 refreshDeps 解决吗 我再研究一下
|
6
knives 2022-03-15 11:09:35 +08:00
个人感觉 swr 官网之所以简单,是因为 swr API 从概念上说就是这么简单 :doge ,至少个人觉得比 useRequest 反倒要清晰点(虽然从功能上不完全对等)。swr 的核心理念就是数据的无感知刷新加载,在 swr 看来,甚至 loading 状态都可以不需要强调。
回到你的问题: 1. isValidating 这个属性我个人的理解和你差不多。不过在实际中我从未用到这个属性…… 2. 是这样。官方的推荐做法是 ['/api/xx', ids] 的形式,参考传入参数的章节。 3. 参考官方条件数据请求的章节。这种场景属于依赖请求的概念。 别的库,react-query 暂未实践过,之前用过 useRequest (非最新版本)。 useRequest 可能是为了保证项目中 API 的统一封装,引入了手动请求之类的 API ,反而把相关组件的生命周期搞复杂了不少。写起来感觉尚可但功能不稳定,之前遇到的问题就是不能按 key 实现全局的数据缓存。 |
7
TWorldIsNButThis OP @knives dependent 官网也是一句话就没了,就说通过 getKey 的函数返回 falsy 值或者抛异常可以实现先获取 a 在获取 b ,但是完全没讲更新的事情
比如更新 id list 以后,id list 可能变可能不变,不变的情况下依然要更新 id 对应的 item ,这个是否是通过 onSuccess 手动触发 dependency 的更新? 想实现的效果是进来获取一次 id list 一次 item ,更新也是只请求一次 id list 和对应的 items |
8
knives 2022-03-15 19:25:38 +08:00
没怎么看懂你的问题。
就你的例子来说,onSuccess 触发 ids 的 mutate 是没必要的。如果是以 useSwr(ids ? ['/api/foo', ids]: null) 形式的依赖调用,在 ids 有变化后这一调用也会被自动触发,不需要手工执行 mutate 。你现在的写法也不能说肯定有问题,但是不是官方建议的写法。 如果 ids 不变也需要触发 item 的更新……还不如直接 ids.concat([]) 触发 ids 变更算了。 |
9
xianyu191031 2022-03-25 17:20:05 +08:00
没看懂楼主的意思,useSwr 核心在于以 path(key)用作缓存,可以试试类似这种写法. id 变了后数据自动就变了
. const getFetcher = (options) => (url) => { ... } const useCustomSwr = (key, options) => { return useSwr(key, getFetcher(options)); } const { data: { ids } } = useCustomSwr(`api/id?id=${id}`); |