这里的数组更新是不可变的,只会创建新数组而不是更新旧数组。
因此,在这个子组件中,Item
应该只对新数组值(索引)调用一次,但它会被调用多次。
代码示例:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
state = {
arr: [10]
};
updateArray = () => {
console.log("updateArray");
let { arr } = this.state;
this.setState({ arr: [...arr, 20] });
};
render() {
const { arr } = this.state;
return (
<div>
{arr.map((el, index) => {
console.log("sasasa", index);
return <Item el={el} key={index} />;
})}
<input type={"button"} value={"submit"} onClick={this.updateArray} />
</div>
);
}
}
class Item extends React.Component {
render() {
console.log("Item");
return <div>{this.props.el}</div>;
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);`
第三次单击按钮时控制台输出将如下所示
Item
Item
Item
在这里我们可以看到 Item
组件针对数组中的所有元素渲染了 3 次;
最佳答案
首先,我警告您,我不是 100% 确定,但这是我的答案。
当您更新 App
组件时,其 render()
方法将多次调用 Item
组件,后者将调用其 render()
方法(即显示 "Item"
的方法。
现在,render()
方法和组件只不过是一个函数,因此,当调用时,它们会被执行:这是JavaScript,两者之间没有React魔法(甚至没有协调) .
但是,当 React 魔法(在本例中是 Reconciliation)发挥作用时?看一下这个 gif,其中我在使用您的codesandbox 时记录了 DOM 元素浏览器:
如您所见,当我单击提交按钮时,由于协调,并非所有 div
元素都会更新,而只是最后一个元素,因为它是新元素。
发生这种情况是因为,由于您分配给 div
的 key
属性,React 识别了旧的 div
,发现它们没有已更改,因此不会修改这些 div
的 DOM。
因此,总而言之,协调和 React render() 方法是两个独立的事物,在两个不同的时刻运行。
这能回答您的问题吗?
关于javascript - React Reconciliation 是这样工作的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55488654/