https://codesandbox.io/s/nift... 沙箱
为什么使用{props.children}父组件更改状态子组件不会触发render?
const ComA = () => {
console.log("ComA render");
return <div>ComA</div>;
};
const ComB = () => {
console.log("ComB render");
return <div>ComB</div>;
};
function App(props) {
console.log("App render");
const [text, setText] = useState("text");
return (
<div className="App">
<ComA />
<ComB />
<button onClick={setText.bind(null, "update_text"+Math.random())}>
updateText({text})
</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
打印:
App render
ComA render
ComB render
const ComA = () => {
console.log("ComA render");
return <div>ComA</div>;
};
const ComB = () => {
console.log("ComB render");
return <div>ComB</div>;
};
function App(props) {
console.log("App render");
const [text, setText] = useState("text");
return (
<div className="App">
{props.children}
<button onClick={setText.bind(null, "update_text" + Math.random())}>
updateText({text})
</button>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(
<App>
<ComA />
<ComB />
</App>,
rootElement
);
打印:
App render
整理一下你的结论:
情况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 />这最终会被编译成
它们执行后返回的时包含<ComA />和<ComB />props的一个对象(ReactElement)
也就是说,返回结果是一个ReactElement全新的引用,而它里面的props也是一个全新的对象,这也就意味着<ComA />和<ComB />的props变了,所以它们会重新渲染。