const [count, setCount] = useState(0);
const fetch = () => {
fetchMoreData(count)
};
const handleClick = () => {
// 每次 fecth 前都要重置一下 count
setCount(0);
fetch()
};
这段代码 每次 handleClick 都要重置 count 的值为 0 ,然后使用 fetch 获取数据,fetch 会使用 count 的值; 如果上面的写法的问题是,count 在使用的时候并没有设置为 0
如果改为 useEffect 方式,如果 count 的值没有变化,又不会触发
const [count, setCount] = useState(0);
const fetch = () => {
fetchMoreData(count)
};
useEffect(() => {
fetch();
}, [count]);
const handleClick = () => {
// count 的值之前就是 0 ,上面的 useEffect 不触发
setCount(0);
};
所以,上面的这种情况该如何处理呢? 刚接触 react 感觉很简单的逻辑,在 react 里处理起来好复杂
1
chanChristin 237 天前
应该是 useState 不会立即更新的问题,你可以换成 useRef 来确认一下,或者是在各处打印一下 useState 的值看看。
|
2
NessajCN 237 天前
你没说你需求是啥
|
3
icoming 237 天前
这样就行了:
const fetch = () => { fetchMoreData(0) }; |
4
withoutxx 237 天前
这种要看原始需求。。。
count 不变为什么需要再调用 fetch ,不清楚 fetch 具体逻辑。 简单点就第一种写法,fetch 直接接收 count 参数就可以。 |
5
xling 237 天前
跟 react 的 fiber 有关,设置后不会立即更新,可以直接把正确的值传递到你需要的函数
|
6
jguo 237 天前
你觉得复杂是因为自己都没有把逻辑理顺。先确定一个根本问题,在什么情况下需要调用 fetchMoreData 。
|
7
cat 237 天前
修改前的问题:setCount 是异步的,它还没执行完就会执行 fetch 了;
修改后的问题:count 值没变化,一直都是 0 ,自然就不会再次触发 useEffect ; |
8
codehz 237 天前 1
网络请求建议直接上 swr 吧,你这个看起来是想做类似分页/无限加载+刷新的效果?那么 swr/infinite 里就可以做了,直接 setcount 然后再 revalidate ,不会有任何冲突,也能实现想要的效果。。。
|
9
iOCZS 237 天前
你这个例子不好,你应该说你有个分页请求,刚进来请求 page=0 ,这时候可以下拉刷新,重新请求 page=0 ;也可以上拉加载 page=1
|
10
devzhaoyou OP @iOCZS 是的,现在就是类似的场景
|
11
devzhaoyou OP @jguo 是的,想要什么是知道的。就是没有理清逻辑,还想简单点写。感觉思想得变下,还没适应 react.
|
12
devzhaoyou OP @codehz 大神啊,是的就是这样的需求
|
13
iOCZS 237 天前
@devzhaoyou 我的想法是 page 仅做存储,也就是 const page = useRef(0),用实际请求到的数据来刷新页面,const list = useState([])。
|
14
wuyiccc 237 天前
react 中 useState 是异步更新的
|
15
gaoryrt 237 天前
const fetch = useCallback(() => {
fetchMoreData(count) }, [count]) 这样行不行 |
16
wuyiccc 237 天前
既然已经确认 cout 为 0 了,就不要通过 state 去获取了,直接传递函数参数 count=0 吧
|
17
evada 237 天前
我觉得 4 楼没问题,可以把 count 当参数传递
|
18
santree 237 天前
导致你这个问题的原因是因为在 React 里,setState 都会默认经过收集和批处理的流程,简单来说他不是立即生效的。
为了处理这个问题,如果你的 count 是一个和渲染相关的值,而且你必须要在 handleClick 时强行进行一次重置为 0 并请求最新值进行设置(也就是说界面上必须反映出这个 count -> 0 -> newCount )我的建议是使用 flushSync 这个 api 对状态设置进行包裹,强制同步更新一次状态。 like this: ```typescript import { flushSync } from 'react-dom'; flushSync(() => { setCount(0); }); ``` 具体可以查看文档: https://react.dev/reference/react-dom/flushSync |
19
santree 237 天前
看之前的回复感觉你更需要把需求理清楚一点,避免这种状态的设置更好。
|
20
cookygg 237 天前
const [count, setCount] = useState(0);
const [,update] = useState({}) const fetch = () => { fetchMoreData(count) }; useEffect(() => { fetch(); }, [count]); const handleClick = () => { // count 的值之前就是 0 ,上面的 useEffect 不触发 setCount(0); // 手动更新 也算一个解决 update({}) }; |
21
devzhaoyou OP 感谢各位,已理清,确实应该通过传值的方式来解决,函数应该尽量不访问外部 state ,有点函数式编程的思想。
同时也确定了一个事情,react 确实不太好做 set 后立刻 get 操作 另外编程思想真得变一变 |
22
devzhaoyou OP @wuyiccc #16 是的,正确的路子
|
23
mwjz 237 天前
封装一个 hooks , 既有 useState 也有 useRef , 不过还是建议用 ahook 的 useRequest
|
24
june4 237 天前
左转 solid-js ,可以 set 后马上 get, 最主要的是,视图函数只运行一次,再也没有这些操蛋的规则
|
26
huangzhiyia 237 天前
import { useState } from 'react';
import useSWR from 'swr'; const fetchMoreData = async (count: number) => { await new Promise((resolve) => setTimeout(resolve, count * 100)); return count } export default function Demo() { const [count, setCount] = useState(0); const { data, error, isLoading } = useSWR(`count-${count}-swr`, async () => { if (count == 5) { throw new Error("count is 5") } return await fetchMoreData(count) }) const handleClick = () => { setCount(0); }; if (isLoading) return <div>Loading...</div> if (error) return <div>{`${error}`}</div> return (<div > <div>{data}</div> <button onClick={() => setCount(count + 1)}>+</button> <button onClick={handleClick}>handleClick</button> </div>) } |
27
mrwangjustsay 237 天前
想研究的深一点可以参考: https://github.com/MrWangJustToDo/MyReact
|
28
realJamespond 237 天前
加个方法 fetchAndCount(count) 包起来用
|
29
yqcode 237 天前
@devzhaoyou #21 react 确实不太好做 set 后立刻 get 操作,这只是 setState 的特性而已,如果你要始终记录一个值,你可以考虑用 useRef
|
30
uni 236 天前
我最喜欢 react 的地方就是它一直在强制使用者用函数式的思维去思考,作为一个被各种各样的副作用强 x 多年的函数式信仰者,我总有一种大仇得报的快感
|
31
jackge0323 236 天前
useState(() => 0)应该就可以解决了吧,使用 useState 的初始化函数。
|
32
magicdawn 236 天前 via Android
你需要一个好用的 useState hook:useRefState, 参见 https://github.com/alibaba/hooks/pull/2348#issuecomment-1794002832 , 是增加了同步支持的 ahooks.useGetState 版本,或者用 react-use.useGetSet
|