React 中添加、删除、变更子组件疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
devzhaoyou
V2EX    React

React 中添加、删除、变更子组件疑问

  •  
  •   devzhaoyou 2024-05-08 12:07:03 +08:00 2331 次点击
    这是一个创建于 588 天前的主题,其中的信息可能已经有所发展或是发生改变。

    React 做一个画图组件,在 CanvaEditor 添加各种 Shape 图形

    <CanvaEditor> <Rect/> <Circle/> .... </CanvaEditor> 

    如果要动态的添加删除 Shape ,就得创建一个保存 shape 属性的列表,然后再遍历渲染

    const (ShapeList) = useState({type, width, heigth ....}) <CanvaEditor> ShapeList.map( (shape) => { if(shapre.type === 'rect') return <<Rect/> else if(shape.type === 'circle') return <<Circle/> } ) </CanvaEditor> // 动态添加图形, 触发 CanvaEditor 重新渲染 const AddShape = (shape) => { ShapeList.push(shape) } 

    疑问:

    1. React 中要添加和删除子组件,都是必须通过有的数据列表转换一道吗?有什么其他操作方法?
    2. 如果上面保存 Shape 的列表 ShapeList 有成千上万个,一旦变更里面的一个 React 都要重新遍历 map ,重新绘制所有子组件吗,这不很浪费吗?
    16 条回复    2024-05-09 00:17:11 +08:00
    horizon
        1
    horizon  
       2024-05-08 12:44:43 +08:00
    加个 key ,可以不更新
    nulIptr
        2
    nulIptr  
       2024-05-08 12:48:23 +08:00
    1.如果不在列表中可以简单的使用条件语句渲染,比如{show&&<div></div>}
    2.map 出来的组件只是虚拟 dom ,通过传入相同的 key 可以保持对应节点不重新渲染(条件比较复杂,大致就是没有任何状态变化),或者你自己可以用 useMemo 优化,
    devzhaoyou
        3
    devzhaoyou  
    OP
       2024-05-08 13:02:41 +08:00
    所以 React 里类似这种场景都是要有数据作为驱动的?数据变,渲染的 UI 也变

    如果是 js 写类似的场景, 写一个 canvaEditor.add(new Shape) 完事了,React 里还要经过数据列表中转一下,个人感觉这不是退步吗?
    codehz
        4
    codehz  
       2024-05-08 13:10:40 +08:00
    如果你这个没有任何层级结构的话
    那确实没有任何优势,react 那种玩法在有复杂层级结构的情况下效果还不错(因为比较只需要考虑一层
    beginor
        5
    beginor  
       2024-05-08 13:27:38 +08:00 via Android
    可以通过 ref 拿到 canvas 元素自己想干啥都行,react 确实是数据/状态驱动的
    ChefIsAwesome
        7
    ChefIsAwesome  
       2024-05-08 13:47:02 +08:00
    首先理解 mvc 框架的应用场景:当一个数据对应多个视图的时候,改一次数据,多个视图自动更新。
    你这是一对一的,用 mvc 当然是多绕了一个圈子。
    HackerJax
        8
    HackerJax  
       2024-05-08 13:47:09 +08:00
    canvaEditor.add(new Shape) 跟 ShapeList.push(shape) 有啥区别?
    zerodli
        9
    zerodli  
       2024-05-08 13:58:08 +08:00
    这是虚拟 dom 这一类前端框架的共同特点,体现的是一个易用性和数据视图的一致性,另外一种以 svelte 、solid 为主的无虚拟 dom 的前端框架,具备编译功能,减轻一些客户端的性能损耗
    maolon
        10
    maolon  
       2024-05-08 14:02:55 +08:00 via Android
    对 你这个要求直接拿 ref 搞是正确做法,实际上 react 对上 canvas 场景基本都是各种 anti-pattern 的 ref 乱飞搞定的
    lisongeee
        11
    lisongeee  
       2024-05-08 14:08:16 +08:00
    数据变会导致 hook 函数重新运行生成新的 vdom ,然后新旧 vdom 对比后再去更新真实 dom 节点

    > 如果上面保存 Shape 的列表 ShapeList 有成千上万个,一旦变更里面的一个 React 都要重新遍历 map ,重新绘制所有子组件吗,这不很浪费吗?

    你这个场景只能说明每次触发更新生成了大量的 vdom ,《重新绘制所有子组件》可不一定,得看新旧 vdom diff 的结果
    okakuyang
        12
    okakuyang  
       2024-05-08 15:04:11 +08:00 via iPhone
    多写写就习惯了,本质上是操作 dom 的方法那么多,改成操作数据减轻心智负担。
    devzhaoyou
        13
    devzhaoyou  
    OP
       2024-05-08 16:58:03 +08:00
    感谢各位,感觉小脑袋瓜又疯狂的在长脑细胞
    devzhaoyou
        14
    devzhaoyou  
    OP
       2024-05-08 16:59:44 +08:00
    @ChefIsAwesome 感谢,学到了
    devzhaoyou
        15
    devzhaoyou  
    OP
       2024-05-08 17:01:36 +08:00
    @zerodli 其实也有疑惑是不是 vue 也是这样,感谢反馈
    mipawn
        16
    mipawn  
       2024-05-09 00:17:11 +08:00
    这个 map 里的 if 判断这块。再单独抽一个组件做这个事情,是可以做到性能优化的
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2966 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 00:32 PVG 08:32 LAX 16:32 JFK 19:32
    Do have faith in what you're doing.
    ubao msn 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