更改订单后,为什么反应对帐会保留固定金额

时间:2018-11-08 22:17:55

标签: reactjs browser google-chrome-devtools firefox-developer-tools

我正在检查react reconciliation。它说,遍历孩子时,React会同时遍历两个孩子列表,并在有差异时生成一个突变。

我举了一个简单的例子:

class ComponentA extends React.Component {

    state = {
        first: true
    }

    clickHandler = () => {
        this.setState({
            first: !this.state.first
        })
    }

    render() {
        return (
            <div className='top'>
                {this.state.first ? <span>xyz</span> : undefined}
                <div>abc</div>
                <div>efg</div>
                <button onClick={this.clickHandler}>click me</button>
            </div>)
    }
}

单击时,第一个孩子(span元素)将进入和退出孩子列表。从React的角度来看,一个接一个地迭代,看起来所有元素都已更改。因此,React应该为所有这四个子项(包括按钮)重新渲染DOM。

但是在Firefox和Chrome中检查DOM检查器时,我发现仅在 span 元素上高亮显示,而不是在所有四个元素上高亮显示,这意味着DOM保留了三个不变的元素。为什么?

highlight is not seen on this picture but the span element gets highlighted (此图片上未显示突出显示,但是单击按钮后span元素会突出显示)

2 个答案:

答案 0 :(得分:0)

在这种情况下,React比较元素属性。来自React文档:

  

相同类型的DOM元素

     

当比较两个React DOM元素时   相同的类型,React查看两者的属性,保持相同   底层DOM节点,并且仅更新更改的属性。对于   例如:

这也是在动态创建元素列表时需要提供密钥的原因。如果未提供该键,并且列表由于属性或状态更改而更改,则需要删除并附加所有列表项。

您可能想阅读下面的文章,其中对这种现象进行了更彻底的解释。 https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318

摘自文章:

  

让我解释一下,密钥是React用来识别DOM的唯一东西   元素。如果将项目推送到列表或将其删除会发生什么   中间有东西吗?如果密钥与React之前假设的相同   DOM元素代表与以前相同的组件。但是那   不再是真的。

答案 1 :(得分:0)

在我的示例中发生的事情是,第一个孩子(JSON_THROW_ON_ERROR)从未真正从children数组中删除,而是仅在span和undefined之间切换。因此,总是有4个孩子,并且重新排序(索引移位)永远不会发生。

这就是为什么react知道匹配元素并仅更新跨度span元素,而其余三个保持不变的原因。