提问一个 React 的问题

2025 年 7 月 9 日
 Plumbiu

像是 fetch 这种请求,需要根据某个 state 变化重新请求,例如 pageSize ,大家一般用以下哪种写法(或者自己有更好的也可说一下):

useEffect:

useEffect(() => {
	fetch(`xxx?pageSize=${pageSize}`)
}, [pageSize])

在 state 发生变化的组件调用 fetch:

<Pagination
  pageSize={pageSize}
  onChange={(pageSize) => {
    fetch(`xxx?pageSize=${pageSize}`)
  }}
/>

我个人更倾向第二种,第一种 useEffect 看上去更方便,不用第二种需要在每个 state 变化的组件调用 fetch ,但是长期维护下来可能会有意想不到的 bug (公司里有个项目因为缓存的 code 和后端返回的 code 不同,导致 useEffect 调用了两边,自己 dev 环境下 mock 很难察觉)

3985 次点击
所在节点    React
20 条回复
foolishcrab
2025 年 7 月 9 日
这是 react fc 出来以后讨论了好几年的问题了,没什么价值。
写第一种的人早就下班了,你从页面上点半天也点不出他什么 bug, 而你还在加班欣赏你优雅的代码。
另外 in practice 第二种绝对是更复杂的,你举一个多参数接口的例子就知道了
donaldturinglee
2025 年 7 月 9 日
第二种比较好的做法是 onChange={handle PageSize},但是这种方式写起来也挺痛苦的
vace
2025 年 7 月 9 日
const [ pageSize, setPageSize ] = useState(10)

const { data } = useSWR(`xxx?pageSize=${pageSize}`, fetch)

<Pagination pageSize={pageSize} onChange={setPageSize} />
realkaiway
2025 年 7 月 9 日
我劝你早点用 TanStack Query ,早下班,还优雅
darkengine
2025 年 7 月 9 日
真实情况下,除了 pageSize 还有其他条件,例如 page ,还有 gender 这些,你怎么处理的?
twk93
2025 年 7 月 10 日
单从问题的两个选择来看肯定选第一个,代码好维护。更好的方案就是楼上说的使用 TanStack Query
BeijingBaby
2025 年 7 月 10 日
react-query
dabingbing
2025 年 7 月 10 日
第一种啊, 两次那是严格模式,生产不会两次
hwdq0012
2025 年 7 月 10 日
严格模式会调 react 函数两次,帮你确定是否是 纯函数
ps:我学 react native 时从文档上看到的,好奇楼主是从哪个途径学习的
yhxx
2025 年 7 月 10 日
现在流行的是这样的:
const { data, isLoading } = useQuery(['data', page, pageSize], () =>
fetch(`xxx?page=${page}&pageSize=${pageSize}`).then(res => res.json())
)

你提的两种选一个的话应该是第一种好一些
kamilic
2025 年 7 月 10 日
react-query or swr 都支持 pagination 的特性
HowardTang
2025 年 7 月 10 日
TanStack Query / useSwr
oky
2025 年 7 月 10 日
https://zh-hans.react.dev/learn/you-might-not-need-an-effect#how-to-remove-unnecessary-effects (你不必使用 Effect 来处理用户事件)
第二种更好,官方已经有指南了,因为你是明确知道什么时候需要改变 pageSize 的。
Asuler
2025 年 7 月 10 日
选第二种,因为第一种有很恶心的闭包问题,你现在只是写了 pageSize 这个参数而已,实际情况可能还有很多表单参数,你在这里面都拿不到最新的。到时候你要维护,你就不断地往 useEffect 的[]里加,一更新就触发调用了,然而用户更多是想点击查询按钮的时候再去调用接口,而不是表单每个值填上后就触发调接口,到时候你维护起来还得加一堆 if 判断
dabennn
2025 年 7 月 10 日
能不用 useEffect 就不用 useEffect ,参数多起来互相打架,改都改不动
realJamespond
2025 年 7 月 10 日
swr 和 qeury ,不用的就是刚入门的
Plumbiu
2025 年 7 月 11 日
@realkaiway 用了下班更晚了哈哈哈,这要多久才能改造完
Plumbiu
2025 年 7 月 11 日
@vace 我很好奇这种库和第一种差别,除了封装好更简洁,还有其他好处吗,因为我第一眼觉得 useSWR 参数变了,不还是要重新请求,假如我有个参数 scene ,只有后端区分场景,前端 ui 不可见,使用 uesRef 保存,state 更新岂不会发起二次请求
Plumbiu
2025 年 7 月 11 日
@Plumbiu 像是这种,模拟了一下 ```jsx

import { useEffect, useRef, useState } from 'react'

function useSWR(url: string) {
useEffect(() => {
console.log(url)
}, [url])
}

function App() {
const sceneRef = useRef<number>(0)
const [count, setCount] = useState(0)
useSWR(`/?scene=${sceneRef.current}`)

return (
<>
<div>{count}</div>
<button
onClick={() => {
setCount(count + 1)
sceneRef.current = count
}}
>
count+
</button>
</>
)
}

export default App

```
hzzhzzdogee
2025 年 7 月 12 日
非专业前端, 个人推崇 swr

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1144118

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX