我正在尝试弄清更新props
之后react库如何重新渲染组件。因此,我有点像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'))
})
}
这适用于第一个渲染cylce。但是,在更改呈现组件的props
之后,console.log
将不再打印。为了弄清楚为什么我在文档中读到ReactDOM.render
仅被称为一次。所以我像通过react的来源一样搜索了google,但是我无法找出props更新后react如何重新渲染组件。你能帮我吗?
答案 0 :(得分:2)
ReactDom.render
调用一次,以将组件安装到DOM中。
在状态更新或道具更改时,React启动对帐过程。
当组件的属性或状态发生变化时,React通过将新返回的元素与先前渲染的元素进行比较来确定是否需要实际的DOM更新。当它们不相等时,React将更新DOM。这个过程称为“和解”。
在此过程中,React在遍历虚拟DOM副本时运行非常简单的diff algorithm。
是否要实施和解?参见Build your own React及其repo。
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++
}
}