react 可以拿到最新数据吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
heishu
V2EX    前端开发

react 可以拿到最新数据吗?

  •  1
     
  •   heishu 2022-07-25 17:17:13 +08:00 2484 次点击
    这是一个创建于 1175 天前的主题,其中的信息可能已经有所发展或是发生改变。

    切换页码时,保存新页码,重新请求新页码数据

    const [pagination, setPagination] = useState({currentPage: 1, ...}) //多余属性没写,如 pageSize 等 const pageChanged = (newPage) => { // 这里用 useState 和 useReducer ,requestData 都无法拿到最新页码数据 setPagination((prev) => ({...prev, urrentPage: newPage})); requestData(); // 这里可以用定时器 100ms 后再执行,以便于拿到最新数据吗? } const requestData() => { // 最新页码不通过函数传参的方法传递,就拿不到最新数据。。。 console.log(pagination.currentPage); //这里拿不到最新的页码 } 
    20 条回复    2022-07-30 01:17:36 +08:00
    max21
        1
    max21  
       2022-07-25 17:19:10 +08:00
    用 useRef 可以
    mufeng
        2
    mufeng  
       2022-07-25 17:20:54 +08:00
    useCallback
    heishu
        3
    heishu  
    OP
       2022-07-25 17:22:00 +08:00
    @max21 useRef 不会触发页码渲染啊
    lalalaqwer
        4
    lalalaqwer  
       2022-07-25 17:28:01 +08:00
    在 useEffect 中请求。你要知道为什么拿不到新数据,因为你的函数创建的时候是用的旧数据。要用新数据你就得重新创建函数。
    heishu
        5
    heishu  
    OP
       2022-07-25 17:36:21 +08:00
    @lalalaqwer useCallback 和 useEffect 意义应该差不多在这里,不过我有个问题是,当有筛选项生效时,需要将 currentPage ,pageSize 等多个值重置为默认值,在 useEffect 中放入这些依赖项的话会触发多次请求的哇?
    towave
        6
    towave  
       2022-07-25 17:45:20 +08:00
    传参最好,其次 useRef 可以的,两个都用不就行了
    anjianshi
        7
    anjianshi  
       2022-07-25 18:10:08 +08:00
    我专门给这种场景写了个工具 hook

    function useStatWithRef(initialState) {
    const [state, rawSetState] = useState(initialState)
    const ref = useRef(state)
    const setState = useCallback((value) => {
    ref.current = value
    rawSetState(value)
    }, [])
    return [state, setState, ref]
    }

    const [state, setState, stateRef] = useStateWithRef(1)
    需要随时获取最新值的地方用 ref ,其他地方用 state
    heishu
        8
    heishu  
    OP
       2022-07-25 18:35:35 +08:00
    @anjianshi 你这个是绑定 dom 用 state ,函数中拿到最新数据用 stateRef 吗?
    ryougifujino
        9
    ryougifujino  
       2022-07-25 18:36:21 +08:00
    setter 的更新是异步的,马上去取肯定拿不到。
    fayetitus
        10
    fayetitus  
       2022-07-25 19:40:31 +08:00
    但我不理解,你为什么要避免给 requestData 传参呢?
    如果你的 pageChanged 是个 handler (起码从名字上看,我猜它视),在这里直接传参调用 requestData 是个非常符合 react 哲学的事情。
    throns
        11
    throns  
       2022-07-25 20:23:17 +08:00   3
    推荐看一下 Dan 写的文章: https://beta.reactjs.org/learn/synchronizing-with-effectshttps://beta.reactjs.org/learn/you-might-not-need-an-effect
    1 、这里的正常操作是:事件调用后,计算最新的筛选项(包括页码和其他的筛选项目),筛选项可以用 state 存起来,把筛选项作为参数传给请求函数进行调用。
    2 、不要滥用 useEffect ,useEffect 会让你很容易会有响应式思想,页码变了,setState 更新页码,然后 useEffect(() =>{ 请求函数 }, [pagination]),这样子会让代码很难维护和问题跟踪。只要是事件触发的操作都尽量避免使用 useEffect 。
    3 、数据请求的话,推荐用 SWR 或者 react-query ,你自己封装也可以,不建议在代码中直接用 useEffect 来写。用请求库能让你的工作事半功倍,这也是 Dan 推荐的( Keep in mind that modern frameworks provide more efficient built-in data fetching mechanisms than writing Effects directly in your components.)
    useEffect 我个人觉得不是一个很好的 Api ,对使用者的心智负担很大,Dan 的两篇文章里面不推荐的用法我基本都写过。官方最近考虑新增一个 API: https://github.com/reactjs/rfcs/blob/useevent/text/0000-useevent.md
    Leviathann
        12
    Leviathann  
       2022-07-25 21:01:35 +08:00
    你这个就是典型的 pub sub 的思维啊,和 react 推崇的不符
    yazoox
        13
    yazoox  
       2022-07-25 23:12:43 +08:00 via Android
    楼主,能不能不要用代码,而是先用文字详细描述一下你的需求么?反正我是不知道你要干嘛。
    heishu
        14
    heishu  
    OP
       2022-07-26 09:18:20 +08:00
    @fayetitus 通过传参传递数据是符合 react 思想的吗,如果是的话我就向这个方向改写了
    heishu
        15
    heishu  
    OP
       2022-07-26 09:18:31 +08:00
    @Leviathann 通过传参传递数据时副歌 react 思想的吗,如果是的话我就向这个方向改写了
    fayetitus
        16
    fayetitus  
       2022-07-26 10:27:57 +08:00 via Android
    @heishu 实打实是的,你解除 requestData 对 currentPage 的依赖,使其变成了一个纯函数。把这个 requestData 当做是 event handler 的一部分,而不是 effect 这个黑大粗概念,这是一种比较好的写法。在没啥时间的时候这么做也足够了。

    更好的写法在 @throns 列出的文档中。尤其是 you may not need useEffct 里专门有一节 fetching data ,使用的样例正是分页请求,解释了现代 react 中怎么实践请求。

    有时间的话,最好通读那些文档。悟道后记得找个现代请求库,比如 swr 之类的,别自己再造轮子……
    zhangleshiye
        17
    zhangleshiye  
       2022-07-29 21:26:23 +08:00
    @throns 看了下 重新回顾了下 感觉还是不一样啊
    throns
        18
    throns  
       2022-07-29 23:17:47 +08:00 via iPhone   1
    @zhangleshiye 不知道你哪里感觉不一样。不过有不同的体会很正常,我的很多体会都是做需求思考得来的。就举个简单的例子:一个列表页,进到页面默认请求第一页的数据(得用 useEffect),可以切换页码请求新的数据。有筛选项,修改筛选项后,此时页码要重置到 1 再请求数据,如果页码和筛选项不是维护到一个 useState 的话,就会很麻烦。为了调用请求函数的时候拿到重置后的页码值,这时候你就本能地想到得用 useEffect 来处理,筛选项和页码变了再调用请求函数,这时候你会发现请求了两次。这个简单的例子,我觉得很多人会遇到过,看 Dan 写的两个文档,立马就应该知道要将筛选项传给请求函数,而不是用 useEffect 。随着业务复杂,你可能会发现 react hook 其实不怎么好用,这也是为什么有一些人很排斥。感觉你之前应该没怎么写过 hook ,你现在看那些文档,我觉得很难有体会,很正常,多踩坑多思考。
    zhangleshiye
        19
    zhangleshiye  
       2022-07-30 01:15:00 +08:00 via Android
    我就是说重读文档感受不一样了 22223
    zhangleshiye
        20
    zhangleshiye  
       2022-07-30 01:17:36 +08:0 via Android
    @throns 就是隔了几天重新看文档, 有新体会的意思
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2733 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 12:26 PVG 20:26 LAX 05:26 JFK 08:26
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86