1
chairuosen 2023-03-02 09:35:00 +08:00
应该是 2 ,担心性能的话,把 table 再封一个?
|
2
leoskey 2023-03-02 09:42:25 +08:00
可以参考这篇文章《 React 组件性能优化:如何避免不必要的 re-render 》 https://mp.weixin.qq.com/s/z9GaB_48LHtL-if4mP-nZQ
|
3
superedlimited 2023-03-02 09:48:02 +08:00
弹窗的 showState 放到 useMemo ,就不会导致 table 重新渲染了
|
4
AyaseEri 2023-03-02 09:56:58 +08:00
把弹窗封成一个独立组件,内部维护 showState ,对外暴露一个 toggle 接口,通过 ref 的形式让外部控制自己的显隐
或者是像 antd 那几个提示一样直接写成一个 function ,每次直接 call function 弹开弹窗 |
5
ChefIsAwesome 2023-03-02 10:26:08 +08:00 via Android
table 一个组件,dialog 一个组件。上面再套一层组件,相当于中间人沟通二者。
多个 dialog 也行。你想象一下 select ,实际也是弹窗。每行来一个,没人觉得奇怪。只要 dialog 关闭的时候,把 Dom 清空就行。 |
6
suzic 2023-03-02 10:32:37 +08:00 via Android
2 。会导致重新渲染么?不太懂 react ,在 vue 里边如果状态和表格无关的话,那部分是不会重新渲染的
|
7
oppddd OP @suzic 会的,因为 vue 是将状态和副作用 render 进行了细粒度的绑定,react 不是,只要 setstate ,父组件子组件都跟着 rerender
|
8
oppddd OP @ChefIsAwesome 再套一个组件也会 rerender ,比如我点击一个按钮,要显示用户详情,那么弹窗就需要知道是什么 userId ,那就会导致状态提升,那么三个组件都会 rerender ;
|
10
joesonw 2023-03-02 10:53:46 +08:00 via iPhone
table 依赖的状态变化了才会刷新,例如有个按钮的 onClick 你直接原地手写的,每次都会变的,要用 useCallback 包起来。类似的检查检查,不会无故刷新的。
|
11
suzic 2023-03-02 10:55:27 +08:00 via Android
@liuxsen93 我猜可以通过包装一个方法,每次调用时手动插入弹窗 dom ,每次用完自动销毁? vue 可以这样玩的,react 应该也可以,原理一样
|
12
ChefIsAwesome 2023-03-02 10:57:47 +08:00 via Android
@liuxsen93 你再琢磨琢磨。ID 存父组件上,传给 dialog ,table 只是改这个 ID ,不用收这个 ID 。
|
13
donlian 2023-03-02 10:58:19 +08:00 via iPhone
子组件用 React.memo 包一下,这样就不会 props 没变就触发 rerender 了
|
14
sjhhjx0122 2023-03-02 11:23:10 +08:00 1
推荐一下我一直在用的维护弹窗的 hook https://github.com/eBay/nice-modal-react 通过这个插件你就可以只创建一个弹窗实例,并且不维护 showState ,切用命令式调用
|
15
dsa999 2023-03-02 11:31:18 +08:00
我觉得弹出层最好放在外层,比如通过 portal 放到 body 下,这样就不会有样式污染的问题。
不过我目前的做法是使用 ReactDom 中的 createRoot 方法,在 body 下创建一个新的根节点处理弹出层。 优点: 1. 不会出现你说的重新渲染问题。 2. 不需要 showState ,通过 render/destroy 控制显隐即可。 缺点: 1. 由于是独立的两个根节点,会造成无法共享 context 等问题,不过可以通过 render 时把数据作为参数传入。 |
16
yuuko 2023-03-02 11:42:33 +08:00
把弹窗放在 cell 组建,显示的时候挂载弹窗,不显示销毁,就不会存在多个实例了
|
17
Ritr 2023-03-02 12:46:17 +08:00
当然是子路由啦,把弹框放到子路由里面就可以了
|
18
monologue520 2023-03-02 13:55:46 +08:00
2 , 有时候是需要 table 重复渲染的,比如说 dialog 中操作改变了 table
|
19
sunwang 2023-03-02 14:01:40 +08:00
这种情况还是倾向于在父级维护 showState ,像新增按钮这种倒是可以和弹窗封装到在一起
|
20
sjhhjx0122 2023-03-02 14:34:43 +08:00
@dsa999 其实有办法拿到上下文的,可以创建一个 ModalProvider 组件专门维护所有弹窗状态和渲染,用 context 传递状态和组件,然后拿这个组件包裹在根组件上,写一个 hook 传递 modal 给 ModalProvide 渲染,如果需要当前组件的上下文就把 ModalProvider 包在当前组件上,就能拿到上下文
|
21
otakustay 2023-03-02 16:05:13 +08:00
把触发弹窗的 button 包个组件,里面管 show 状态,这样 table 就不会渲染了。至于多个弹窗实例,用{show && <Modal />}管呗,全局遮罩层一下,不就只有一个了么
|
22
jjwjiang 2023-03-02 16:16:45 +08:00
在 react hooks 里不应该恐惧一般情况下产生的 re-render 。整个组件级别的 re-render 依然会被 react 优化成只对弹窗部分 re-render
|
23
dsa999 2023-03-02 18:19:56 +08:00
@sjhhjx0122 嗯,不过大多数场景下 render 时传参也够用了。弹出层从交互上来看,本来就是处理额外的独立逻辑的嘛
|
24
oppddd OP @sjhhjx0122 看了这个仓库,用着很舒服!大佬啊
|