V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
heishu
V2EX  ›  前端开发

react 可以拿到最新数据吗?

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

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

    const [pagination, setPagination] = useState({currentPage: 1, ...}) //多余属性没写,如 pageSize 等
    const pageChanged = (newPage) => {
    
        // 这里用 useState 和 useReducer ,requestData 都无法拿到最新页码数据
        setPagination((prev) => ({...prev, currentPage: 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 useStateWithRef(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
    @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:00 via Android
    @throns 就是隔了几天重新看文档, 有新体会的意思
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1166 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 18:09 · PVG 02:09 · LAX 10:09 · JFK 13:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.