React中dom渲染和render到底是啥意思?

#1

最近看react文档发现一个问题,因为是英文一直搞不明白确切的意思,求大神解惑!

  1. 第一种情况:
    setState会触发组件重新渲染,但是如果2者相同,在不使用pureRender的情况下会发现componentDidUpdate被执行,说明组件render函数有执行过。但是通过chrome审查元素会发现,组件div根本没有重新生成,如果渲染会有一个红色跳动。
    2.第二种情况:
    如果setState改变了组件的className,style,children等属性。render执行,组件div在审查元素查看并不跳动而是,class 或者内容跳动。说明divDOM并没有重新生成,而是渲染内部部分内容。
    3.第三种情况:
    改变包裹组件的dom节点类型,比如由span改为div,render后,会生成新的div。
    也就是说每次组件render后形成一个虚拟dom,然后拿这个dom和已经mount的dom去比较。然后再根据上面的三种情况去决定是否重新生成,还是渲染部分内容。
    我发现的问题是:比如我有一个<ul>{list.map(item=><li>{item.content}</li>)}</ul>,在list中添加新的item时,只有新生成的li在chrome审查元素中跳动,也就是说ul组件更新,但是ul实际的DOM节点还是原来的,但是如果我delete一个item时,ul会跳动,也就是ul实际dom节点重新生成了。如何避免减少的时候不重新渲染这个dom呢?不知道我理解有没有错?求大神解惑啊。
1 Like
#2

你可以详细的看一下react的diff在关于DOM更新那一块的东西,网上有好多,diff会在计算之后做出最少的改动来更新DOM,就比如说你只更改了style中的一个属性,diff通过对比发现和之前的元素只是style中一个样式不对,它就会只改这一个样式,而不会去重新渲染整个DOM元素,还有就是删除增加元素什么的,网上都有很好的解释。

#3

我的问题其实就是增删元素啊。增加不变,删除改变了啊。能给个你说的链接?

#4
#5

render负责在服务器断渲染虚拟DOM树 并将此DOM树推到前段浏览器中,每次修改DOM树都会在服务器端渲染之后在显示

#6

根本就没用到服务器端,完全前端啊。

#7

是否有可能chrome在审查元素中的跳动 并不一定代表着对应的dom被变动

于是有如下猜想:
按增加<li>子节点时 <li>跳动的逻辑
删除<li>子节点 <li>跳动 但是<li>已经被删除 无法通过跳动<li>来告知谁被删除
只能通过其父节点的跳动来展示

本尝试通过添加时间戳 来佐证此猜想
但是貌似数据变化导致dom变化是单向的
也就是说 数据变化dom一定变化 数据没变化dom可能变化

不知题主现在是否有了答案 如果有期望分享一下

追加:
当我把li拆分为子组件后
通过componentWillUnmount可以看到每次删除li只是写卸载掉当前li
并未卸载ul然后重新挂载新的dom
如果删除ul 所有li的componentWillUnmount都会触发
因此应该可以佐证上述的猜想
也就是ul跳动 并不代表ul的dom被重新渲染