我的场景是这样的:
我先把 API a 和 b 用 react query 抽象成 hook:
const useFetchA = (params) => {
return useQuery(['fetchA', params], async () => {
return await API.a(params)
})
}
// useFetchB 也类似,就不写了
然后在很多组件上都有这样的两行:
const resA = useFetchA('xxx');
const resB = useFetchB('yyy');
我也想过要 API.a 和 API.b 放在一个 hook 里,但是这样,单独使用 API.a 或 API.b 的时候就不方便了。
也想过把 useFetchA 和 useFetchB 再放在一个 hook 里,类似这样:
const useFetchAandB = (params) => {
const {data: resA} = useFetchA(params)
const {data: resB} = useFetchB(resA)
}
不知道这样是否可行?有什么隐患?是否符合规范?
1
codehz 2022-09-15 23:41:25 +08:00
react query 不是自带缓存管理的吗(
重复写又不会重复请求 |
2
tonytonychopper 2022-09-15 23:56:19 +08:00
我理解 hook 就是可以随便组合的,只要逻辑清晰就行了
|
3
RRRSSS OP |
4
codehz 2022-09-16 00:12:04 +08:00
@RRRSSS 这就是为啥不应该用 useEffect 来做这种操作(
https://blog.skk.moe/post/why-you-should-not-fetch-data-directly-in-use-effect/ |
5
changwei 2022-09-16 00:32:41 +08:00 via Android
用 swr ,把前一个 swr 请求的返回结果作为下一个 swr 的 key 即可,不用担心缓存问题,swr 会自动帮你解决
|
6
RRRSSS OP @changwei emm..
我换个例子吧,不是请求,只是一个副作用,比如第一个 hook 是改 title ,第二个 hook 是根据这个 title 是否是 'homepage' 而去 useWindowSize 。好吧,我没编出来。就是这个意思,怎么弄呢、 |
7
RRRSSS OP @codehz @tonytonychopper 关键是如果想要这种就不行了,不能放在 if 里:
```js const useFetchAandB = (params) => { const {data: resA} = useFetchA(params) if (resA === 'foo') { const {data: resB} = useFetchB(resA) } } ``` 这样就不能抽象成 hook 了吧 |
8
Pastsong 2022-09-16 00:51:31 +08:00
useFetchAandB
useFetchA useFetchB 同时存在,想用啥用啥 |
10
CptDoraemon 2022-09-16 02:18:30 +08:00
@RRRSSS
```js const useFetchAandB = (params) => { const {data: resA} = useFetchA(params); const {data: resB, doFetchB} = useFetchB(); const previousResARef = useRef(resA); useEffect(() => { if (previousResARef.current !== 'foo' && resA === 'foo') { } }) ``` |
11
CptDoraemon 2022-09-16 02:20:00 +08:00
tab 到回复了 lol
```js const useFetchAandB = (params) => { const {data: resA} = useFetchA(params); const {data: resB, doFetchB} = useFetchB(); const previousResARef = useRef(resA); useEffect(() => { if (previousResARef.current !== 'foo' && resA === 'foo') { doFetchB(resA) } }) ``` |
12
codehz 2022-09-16 10:29:32 +08:00 1
(再动态一点可以考虑包一层组件,虽然 hook 不能写条件,但是组件可以随便加
做类似无限滚动的话还可以用 useSWRInfinite |
13
jjwjiang 2022-09-16 11:17:11 +08:00
B 既然依赖 A 的结果,那你定义 useFetchB 的时候给个入参就行了,这样所有用到 fetchB 的地方就必须传入 A 的结果
如果 A 的查询和每个页面内容无关,那直接把 A 写到 useFetchB 里面去 |
14
tonytonychopper 2022-09-17 00:36:31 +08:00
@RRRSSS #7 这样写本来就会有坑,如果一定要这么写的话,不如在 useFetchB 内部做判断:
function useFetchB if resA === 'foo' then do something |