整理一下你的结论:
情况1,调用props.children,ComA 和 ComB不会重新渲染;
情况2,直接在App组件中的render函数内嵌ComA和ComB,会引发重新渲染;
情况1
ComA 和 ComB在App的render函数中是以props.children的形式体现出来的。这个props是App的props,而App渲染时,其props并未变化,相应的props.children,它是ComA 和 ComB的jsx形式,也没有变化,也就是说ComA 和 ComB的props同样没有变化,所以不会重新渲染。
情况2
ComA 和 ComB的形式在App的render函数中是<ComA />、<ComB />这最终会被编译成
React.createElement(ComA,?null)
React.createElement(ComB,?null)
它们执行后返回的时包含<ComA />和<ComB />props的一个对象(ReactElement)
export function createElement(type, config, children) {
// 重点在这里,重新声明了props属性的引用
const props = {};
...
return ReactElement(
type,
key,
ref,
self,
source,
ReactCurrentOwner.current,
props,
);
}
也就是说,返回结果是一个ReactElement全新的引用,而它里面的props也是一个全新的对象,这也就意味着<ComA />和<ComB />的props变了,所以它们会重新渲染。
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…