背景是这样的,页面上一些按钮,每次点的时候都去调用后端接口,并且把状态保存起来,然后我用 useEffect 去做,每次数据变化都时候去调用后端接口,然后第一次进页面都时候要把状态请求过来,这样会导致数据变化,然后多请求一次后端接口,有没有什么好的方案去解决。 代码大致这样:
useEffect(() => {
axios.get(xxx).then((res) => {
setData(res);
});
}, []);
useEffect(() => {
axios.post(xxx);
}, [data])
1
zeyexe 2021-04-09 10:33:07 +08:00
|
2
zeyexe 2021-04-09 10:34:59 +08:00
第二个 useEffect 其实可以改成函数,然后代替 setData 的位置。
|
3
vision1900 2021-04-09 10:37:20 +08:00
|
4
pradon 2021-04-09 10:46:08 +08:00
|
5
sgiyy 2021-04-09 10:49:23 +08:00
1. 如二楼,post 请求写到函数里,在修改后调用
2. 加个是否数据初始化完成的状态,放在第二个 useEffect 的依赖里,然后判断一下 |
6
q673115816 2021-04-09 10:52:21 +08:00 via Android
再监听个点击状态?
|
7
PeakFish 2021-04-09 10:53:28 +08:00
第一次 data 是 undefinde 吧 , 写个 if 不行吗?
``` if (data) { } ``` |
8
PeakFish 2021-04-09 10:53:49 +08:00
第一次 data 是 undefinde 吧 , 写个 if 不行吗?
``` if (data) { ... } ``` |
9
PeakFish 2021-04-09 10:54:57 +08:00
|
10
ahaya 2021-04-09 10:57:11 +08:00
初始状态为空,你可以在状态里维护一个 pre 指向上一个状态(其实就是链表) 这样调用接口的时候先判断之前的状态,做一下判空就行了
|
11
xingguang OP |
12
sweetcola 2021-04-09 11:06:57 +08:00
我看你好像是需要根据 data 变化后执行 post,所以你可以试试这样做。用 useRef 来储存第一次获得的 data,在第二个 useEffect 进行 ref 和 data 是否相等判断。
代码: const dataRef = useRef(); const handleSetData = (data) => { setData(data); dataRef.current = data; } useEffect(() => { const fn = async () => { const res = await axios.get(xxx); handleSetData(res); }; fn(); }, []); useEffect(() => { if (dataRef.current === data) { return; } axios.post(xxx); // 如果 xxx 里涉及到 setData,用 handleSetData 代替 }, [data]) |
13
xiaoming1992 2021-04-09 13:01:26 +08:00
如 5 楼第二点,加一个是否初始化完成的标记,可以放在 ref 里,应该是对当前的代码逻辑侵入最小的,放在 ref 里也不用依赖它
|
14
CodingNaux 2021-04-09 17:13:28 +08:00
第一个 useEffect 是只在一次 render 之后执行
第二个 useEffect 是从二次 render 之后开始执行 如果是这样的,可以加个 ref 表示是否第一次执行 ```jsx const firstRenderRef = React.useRef(true); useEffect(() => { firstRenderRef.current = false; axios.get(xxx).then((res) => { setData(res); }); }, []) ``` |
15
CodingNaux 2021-04-09 17:15:03 +08:00 1
第一个 useEffect 是只在一次 render 之后执行
第二个 useEffect 是从二次 render 之后开始执行 如果是这样的,可以加个 ref 表示是否第一次执行 ```jsx const firstRenderRef = React.useRef(true); useEffect(() => { firstRenderRef.current = false; axios.get(xxx).then((res) => { setData(res); }); }, []); useEffect(() => { if (firstRenderRef.current) return; axios.post(xxx); }, [data]) ``` |
16
xingguang OP @CodingNaux 感谢,最后确实还是用 ref 做的,我个人喜好不是很喜欢用 ref,不到无法解决的地步不太喜欢用,不过还是屈服于现实了
|
17
CodingNaux 2021-04-09 17:24:37 +08:00
@CodingNaux 上面代码有问题。 两个 useEffect 调换下顺序,或者在最后写个单独的 effect 去改 flag,useEffect 的顺序有影响的。
|