react 怎么给每个组件都加上刷新按钮?感觉这种需求很难搞。。修改 antd 的源码能行吗 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
790002517zzy
V2EX    React

react 怎么给每个组件都加上刷新按钮?感觉这种需求很难搞。。修改 antd 的源码能行吗

  •  
  •   790002517zzy
    zzy-life 2024-05-14 10:29:50 +08:00 4487 次点击
    这是一个创建于 515 天前的主题,其中的信息可能已经有所发展或是发生改变。
    比如这样的需求,有什么比较好的方式吗?刷新当前组件的方式也可以。


    组件都是用 antd 的 Modal 弹出来的,只要刷 Modal 就行:
    33 条回复    2024-05-15 13:01:29 +08:00
    rookie2luochao
        1
    rookie2luochao  
       2024-05-14 10:47:07 +08:00
    看不到你的图片,组件都加上刷新是什么意思,从来没遇到过所有组件刷新,你的组件指的是业务组件,还是要包含 UI 组件,如果是组件里面的接口有联动,可以用 rxjs 构造成可观察对象,或者用 react-query 来做组件之间的接口联动

    demo: https://github.com/rookie-luochao/create-vite-app-cli/tree/master/template-react-ts#%E8%B0%83%E7%94%A8%E6%8E%A5%E5%8F%A3react-query-%E6%94%AF%E6%8C%81%E8%87%AA%E5%8A%A8loading%E5%92%8C%E6%8E%A5%E5%8F%A3%E8%AF%B7%E6%B1%82%E8%81%94%E5%8A%A8
    mxT52CRuqR6o5
        2
    mxT52CRuqR6o5  
       2024-05-14 10:57:53 +08:00
    写个能传 children 的组件
    790002517zzy
        3
    790002517zzy  
    OP
       2024-05-14 11:04:29 +08:00
    @rookie2luochao 看不到图应该是梯子问题 只需要刷新最前面的组件就行,类似于刷新 z-index 最高的 Modal 即可(目的是刷新数据)


    @mxT52CRuqR6o5 这样的话就需要改每个页面了
    rookie2luochao
        4
    rookie2luochao  
       2024-05-14 11:07:12 +08:00
    @790002517zzy 你的目的是刷新数据的话,可以看看我发的那个链接,那个库能很好的处理跨组件之间的接口联动刷新问题,你也可以用 rxjs 实现
    douxc
        5
    douxc  
       2024-05-14 11:07:20 +08:00
    呃,modal 弹出来的时候请求一次数据?那就在 modal 显示的时候处理一下,useEffect 监听 open/close 状态,发现是显示就去获取数据
    790002517zzy
        6
    790002517zzy  
    OP
       2024-05-14 11:09:24 +08:00
    比如如果用 iframe 实现 Modal 可以使用 reload 让浏览器刷新(图 1 就是这样实现的)
    但是组件形式如果用 reload 会导致这个 url 刷新,而需求只需要刷新 Modal
    790002517zzy
        7
    790002517zzy  
    OP
       2024-05-14 11:10:25 +08:00
    @douxc modal 弹出来后,数据会变动(其他用户操作了这个数据),所以用户需要一个刷新按钮刷新当前 modal 中的数据
    790002517zzy
        8
    790002517zzy  
    OP
       2024-05-14 11:15:15 +08:00
    @rookie2luochao RxJS 好像可以,看起来像是会自动更新数据?可我很多个页面都用了 modal ,这样改的话也需要每个页面都去改。 还不如重新封装 modal 组件了
    googleaccount
        9
    googleaccount  
       2024-05-14 11:30:28 +08:00
    追求数据实时性 考虑用 websocket ?
    790002517zzy
        10
    790002517zzy  
    OP
       2024-05-14 11:32:36 +08:00
    @googleaccount 不是实时性,就是用户想点一下就看最新的数据,而不是 F5 刷新还要点半天才能打开这个 modal
    CHTuring
        11
    CHTuring  
       2024-05-14 11:35:16 +08:00
    1 、如果只是数据数据更新的话,每次 modal 关闭的时候销毁内部的组件就可以实现。
    2 、如果是希望复用,一个高阶函数就能实现
    gaogang
        12
    gaogang  
       2024-05-14 11:39:07 +08:00
    组件内部可变化的数据是拿不到吗?
    直接用 props 传进去的话,传入的值变了的话,组件不是会就会重新渲染了吗
    looplj
        13
    looplj  
       2024-05-14 11:41:20 +08:00
    基于 antd 的 modal 封装一个 modal ,固定给 modal 新增一个 refresh 按钮和 refresh 的 action 。

    refresh 的默认行为可以是将 children 替换为一个 loading 页面,然后再重新加载 children ,就会触发 children 重新加载吧。
    leroy20317
        14
    leroy20317  
       2024-05-14 11:49:36 +08:00
    Modal.useModal() modal 提供的 hooks 上下文可以用不?
    ZZITE
        15
    ZZITE  
       2024-05-14 11:55:33 +08:00
    refresh 数据不就行了吗?你的数据是在哪一层,通过什么形式获取的?
    我举个例子,假设是在 modal 内部自己通过 react-query 这种请求管理工具获取的数据,那么在刷新按钮点击时执行一次 refetch 或者 invalidateQueries ,modal 内的数据就更新了。可以通过高阶组件的形式,把所有 modal 都包裹一下,统一加上刷新按钮的功能。
    leroy20317
        16
    leroy20317  
       2024-05-14 11:56:09 +08:00
    要是只是想重新 render 一次,const [, setState] = useState({}); setState({}) 也可以的
    veveue
        17
    veveue  
       2024-05-14 13:16:47 +08:00
    这就要看 modal 获取数据的逻辑怎么写的了
    cydian
        18
    cydian  
       2024-05-14 13:45:59 +08:00
    swr
    ColdBird
        19
    ColdBird  
       2024-05-14 14:04:29 +08:00
    整个组件包一下不就得了,按你说的只对 modal 做操作那不是简单的很,不至于上升到对全部 Antd 组件的处理。
    * 方案 1:props 里只传 data ,这样内部不关心 data 的变更,外层 refresh 之后自己请求数据,内层更新 UI
    * 方案 2:props 里传 onLoad 作为加载回调、payload 作为触发器,监听 payload 的变化调用 onLoad 请求数据,再这个基础上抽象一下,不难实现
    790002517zzy
        20
    790002517zzy  
    OP
       2024-05-14 14:10:10 +08:00
    就是想刷新 Modal 嵌套的组件...这样的话就达到了刷新数据的效果
    上面说的从数据获取上着手就要每个页面都要改,工作量太大
    kinghly
        21
    kinghly  
       2024-05-14 14:22:36 +08:00 via Android
    最简单就是关闭时销毁 modal
    790002517zzy
        22
    790002517zzy  
    OP
       2024-05-14 14:25:19 +08:00
    @kinghly 是的,destroyOnClose 属性,但是不够理想,用户需要关闭 modal 重新打开才可以
    @leroy20317 写在 html 中的
    @ZSeptember refresh 怎么刷新(或者逻辑是关闭打开) modal 中的组件呢?
    vanchKong
        23
    vanchKong  
       2024-05-14 14:36:28 +08:00
    写个组件,传入刷新方法就行了呗
    Wanex
        24
    Wanex  
       2024-05-14 14:38:30 +08:00
    Modal 的内容不是你自己传进去的吗,你自己搞个有刷新按钮的高阶组件,需要刷新的组件套进去就行了
    790002517zzy
        25
    790002517zzy  
    OP
       2024-05-14 14:42:45 +08:00
    update 方法可以更新 modal 窗口,问题来了,怎么获取它?可以在根页面直接通过 ref 拿到顶层 modal 的 dom 吗?
    gaoxiu
        26
    gaoxiu  
       2024-05-14 14:43:07 +08:00
    @790002517zzy #20 意思是 只需要刷新 Modal 内的组件?那么这个组件的数据是自治的吧?是的话就挺简单的:
    1. 用 Modal 的 closeIcon 重新定义关闭图标,借用这个 api 添加一个刷新按钮(记得阻止刷新按钮的冒泡事件)
    2. 需要刷新的子组件添加 key 属性,每次刷新的时候更新这个 key
    theohateonion
        27
    theohateonion  
       2024-05-14 15:00:30 +08:00
    噢,你不想改每个子组件但是又想给所有用了 modal 的组件加上刷新功能。26 楼的方法可行,刷 key 就可以了。

    能解决问题,但是也是给自己埋坑。万一哪个组件又不想自动刷新了呢。。

    最好的办法还是重新封装一个 modal 组件,是否需要刷新这个标志由 modal 传入子组件,子组件自己决定刷不刷。
    DesnLee
        28
    DesnLee  
       2024-05-14 15:04:03 +08:00
    给要刷新的组件树最顶层的组件一个 key ,改变这个 key 组件内部就会重新渲染
    790002517zzy
        29
    790002517zzy  
    OP
       2024-05-14 15:10:17 +08:00
    @gaoxiu 感谢好像搞定了,把组件替换掉,更换下引用就行
    谢谢大家
    withoutxx
        30
    withoutxx  
       2024-05-14 15:12:12 +08:00
    试了下骚操作,不要在真实项目这么玩,Modal.useXXX 应该都会失效
    https://stackblitz.com/edit/react-f4out2


    790002517zzy
        31
    790002517zzy  
    OP
       2024-05-14 15:56:57 +08:00
    新问题...把所有的 Modal 改成 26#之后,节点直接无限刷新了,页面不出来
    790002517zzy
        32
    790002517zzy  
    OP
       2024-05-14 16:06:03 +08:00
    没事了没事了,一键替换的时候重复循环了
    natamox
        33
    natamox  
       2024-05-15 13:01:29 +08:00
    setState({})
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1388 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 16:49 PVG 00:49 LAX 09:49 JFK 12:49
    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