我会为了上下文发布你的实际代码:
class Application extends React.Component {
render() {
return (
<div>
{/*
Clicking this component only logs
the parents render function
*/}
<DynamicParent>
<Child />
</DynamicParent>
{/*
Clicking this component logs both the
parents and child render functions
*/}
<StaticParent />
</div>
);
}
}
class DynamicParent extends React.Component {
state = { x: false };
render() {
console.log("DynamicParent");
return (
<div onClick={() => this.setState({ x: !this.state.x })}>
{this.props.children}
</div>
);
}
}
class StaticParent extends React.Component {
state = { x: false };
render() {
console.log("StaticParent");
return (
<div onClick={() => this.setState({ x: !this.state.x })}>
<Child />
</div>
);
}
}
function Child(props) {
console.log("child");
return <div>Child Text</div>;
}
当您在应用程序渲染中编写此代码时:
<StaticParent />
所呈现的内容是这样的:
<div onClick={() => this.setState({ x: !this.state.x })}>
<Child />
</div>
事实上,大致上发生的情况是这样的:
function StaticParent(props) {
return React.createElement(
"div",
{ onClick: () => this.setState({ x: !this.state.x }) },
React.createElement(Child, null)
);
}
React.createElement(StaticParent, null);
当您像这样渲染您的DynamicParent:
<DynamicParent>
<Child />
</DynamicParent>
这实际上是发生的事情(再一次粗略地说)
function DynamicParent(props) {
return React.createElement(
"div",
{
onClick: () => this.setState({ x: !this.state.x }),
children: props.children
}
);
}
React.createElement(
DynamicParent,
{ children: React.createElement(Child, null) },
);
这在两种情况下都是孩子:
function Child(props) {
return React.createElement("div", props, "Child Text");
}
这是什么意思?在您的 StaticParent 组件中,每次调用 StaticParent 的渲染方法时,您都会调用 React.createElement(Child, null)
。而在 DynamicParent 中,Child 只创建一次并作为属性传递。而且由于 React.createElement
是纯函数,所以它可能在某个地方进行了记忆以提高性能。
在 DynamicParent 情况下,会导致 Child 的重新渲染的是其属性的变化。例如,如果父组件的状态被用作 Child 的属性,那么这将在两种情况下触发重新渲染。
我真的希望 Dan Abramov 不会在评论中出现,否则他可能会批评我的回答(虽然写起来很痛苦但也很有趣)。