[英]How does the react library rerender components
I am trying to figure out how the react library rerenders components after updating the props
.我试图弄清楚 react 库在更新props
后如何重新呈现组件。 Therefor I kind of monkey patched ReactDOM.render
method like so:因此,我有点猴子修补ReactDOM.render
方法,如下所示:
const oldRender = ReactDOM.render
ReactDOM.render = function(){
// ......
console.log("42")
return oldRender.call(this, ...arguments, () => {
console.log("done")
document.dispatchEvent(new Event('react-dom-rendered'))
})
}
This works for the first rendering cylce.这适用于第一个渲染周期。 But after the props
of the rendered component changed, the console.log
s are not printed anymore.但是在渲染组件的props
改变后, console.log
就不再打印了。 In order to figure out why I read in the docs that ReactDOM.render
will only be called once .为了弄清楚为什么我在文档中ReactDOM.render
只会被调用一次。 So I searched through google just like through react's sources but I was not able to find out how react manages to rerender a component after a props update.所以我通过谷歌搜索,就像通过 react 的来源一样,但我无法找出 react 如何在道具更新后重新渲染组件。 Could you help me here?你能帮帮我吗?
ReactDom.render
called once to mount the component into the DOM.调用一次ReactDom.render
将组件挂载到 DOM 中。
On state update or on props change, React starts a Reconciliation process.在 state 更新或 props 更改时,React 启动协调过程。
When a component's props or state change, React decides whether an actual DOM update is necessary by comparing the newly returned element with the previously rendered one.当组件的 props 或 state 发生变化时,React 通过将新返回的元素与之前渲染的元素进行比较来决定是否需要进行实际的 DOM 更新。 When they are not equal, React will update the DOM.当它们不相等时,React 将更新 DOM。 This process is called “reconciliation”.这个过程被称为“和解”。
In this process, React runs a pretty simple diff algorithm while traversing a copy of Virtual DOM.在这个过程中,React 在遍历 Virtual DOM 的副本时运行了一个非常简单的diff 算法。
Want to implement the Reconciliation ?想要实施和解? See Build your own React and its repo .请参阅构建您自己的 React及其存储库。
function reconcileChildren(wipFiber, elements) {
let index = 0
let oldFiber =
wipFiber.alternate && wipFiber.alternate.child
let prevSibling = null
while (
index < elements.length ||
oldFiber != null
) {
const element = elements[index]
let newFiber = null
const sameType =
oldFiber &&
element &&
element.type == oldFiber.type
if (sameType) {
newFiber = {
type: oldFiber.type,
props: element.props,
dom: oldFiber.dom,
parent: wipFiber,
alternate: oldFiber,
effectTag: "UPDATE",
}
}
if (element && !sameType) {
newFiber = {
type: element.type,
props: element.props,
dom: null,
parent: wipFiber,
alternate: null,
effectTag: "PLACEMENT",
}
}
if (oldFiber && !sameType) {
oldFiber.effectTag = "DELETION"
deletions.push(oldFiber)
}
if (oldFiber) {
oldFiber = oldFiber.sibling
}
if (index === 0) {
wipFiber.child = newFiber
} else if (element) {
prevSibling.sibling = newFiber
}
prevSibling = newFiber
index++
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.