【问题标题】:React state array updates/renders entire array, is there a work-around?React 状态数组更新/渲染整个数组,有解决方法吗?
【发布时间】:2017-12-02 23:53:31
【问题描述】:

这是基本的想法......

constructor(props) {
    super(props);
    this.state = {
        children: [{id:1},{id:2}], // HERE ARE THE TWO OBJECTS
        style: {top: 0}
    };
}

现在假设我更新了这两个对象之一,但这些对象被映射到一个组件数组。

<div className="thread">
    {this.state.children.map((child) =>
        <Post
            key={child.id}
            id={child.id}
        />
    )}
</div>

现在...当我更新其中一个对象时...

changeID (id, newID) { // this is a different function, just an example
    let temp = this.state.children;
    for (let i = 0; i < temp.length; i++) {
        if (temp[i].id === id) {
            temp[i].id = newID; // <- update this
        }
    }
    this.setState({
        children: temp // <- plug temp[] back as the updated state
    });
}

我将新状态重新放入,但它会更新每个映射的对象。

// on one change to one element
id 1 POST UPDATED
id 2 POST UPDATED

1) 它是重新渲染 EVERY 组件(在映射数组中)还是足够聪明地判断作为道具传递给映射组件的状态值是相同的?

2) 如果阵列明显更长,处理能力是否会非常昂贵?

3) 如果是,我怎样才能更好地解决这个问题?建设性的批评是值得赞赏的。

谢谢!

【问题讨论】:

  • 你怎么知道它正在更新每个对象?
  • @MayankShukla componentDidUpdate(){console.log("UPDATED");}

标签: reactjs state prop


【解决方案1】:

这就是react 的工作原理,每当您更改任何state 变量时,它都会重新渲染完整的组件并更新虚拟dom 而不是实际的dom,然后它将检查这两者之间的差异并仅更改实际 dom 中的特定元素。

根据DOC

React 提供了声明式 API,因此您不必担心 每次更新都有哪些变化。

React Only Updates What's Necessary:

React DOM 将元素及其子元素与前一个元素进行比较, 并且仅应用将 DOM 带到 想要的状态。

DOM Elements Of The Same Type:

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

例如:

<div className="before" title="stuff" />

<div className="after" title="stuff" />

通过比较这两个元素,React 知道只修改底层 DOM 节点上的 className。

Use of Keys:

React 支持 key 属性。当孩子有钥匙时,React 使用 将原始树中的孩子与 后续树。

Imp:

Keys 帮助 React 识别哪些项目已更改、添加或正在更改 删除。键应该给数组内的元素以给出 元素一个稳定的身份。数组中使用的键在它们的兄弟中应该是唯一的。但是,它们不需要是全球唯一的。

例如:

<ul>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

<ul>
  <li key="2014">Connecticut</li>
  <li key="2015">Duke</li>
  <li key="2016">Villanova</li>
</ul>

现在 React 知道键为 '2014' 的元素是新元素,键为 '2015' 和 '2016' 的元素刚刚移动。

查看这篇文章:How Virtual-DOM and diffing works in React

【讨论】:

  • 哇,多么棒的回应。因此,我知道 Virtual-DOM 维护 actual DOM 并进行比较(精彩文章),但容器组件的子组件每个都调用 componentDidUpdate() 方法。该方法名称的含义是否与我认为的含义不同?当我更新状态时,网页/组件似乎并没有刷新所有内容,所以我认为你已经一针见血了。
  • @JohnCullen 很高兴,它帮助了你:)
猜你喜欢
  • 1970-01-01
  • 2020-09-05
  • 1970-01-01
  • 1970-01-01
  • 2018-05-01
  • 2020-10-24
  • 1970-01-01
  • 2021-09-20
相关资源
最近更新 更多