提问一个 React 的问题

111 天前
 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 很难察觉)

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

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

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

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

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

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

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

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

© 2021 V2EX