这个问题很老了,但既然你似乎没有得到令人满意的答案,我也试一试。
正如你自己观察到的,改变
// Scenario A
<div onClick={() => this.setState({})}>
{this.props.children}
</div>
到
// Scenario B
<div onClick={() => this.setState({})}>
<Child />
</div>
事实上,最终会
容器渲染
子渲染
在控制台中,每次单击时。
现在,引用你的话
据我了解,如果 setState() 被触发,Container 组件的渲染函数将被调用,所有子元素都应重新渲染。
你似乎非常接近理解这里发生的事情。
到目前为止,你是对的,因为Container
'srender
被执行,所以从它返回的组件必须调用它们自己的render
方法。
现在,正如你所说的,正确的,
<Child />
// is equal to
React.createElement(Child, {/*props*/}, /*children*/)
从本质上讲,你从上面得到的只是object
描述要在屏幕上显示的内容,一个 React Element。
这里的关键是要了解当的React.createElement(Child, {/*props*/}, /*children*/)
执行发生,在上述各场景。
那么让我们看看发生了什么:
class App extends Component {
render() {
return (
<Container>
<Child/>
</Container>
)
}
}
class Container extends Component {
render() {
console.log('Container render');
return (
<div onClick={() => this.setState({})}>
{this.props.children}
</div>
)
}
}
class Child extends Component {
render() {
console.log('Child render');
return <h1>Hi</h1>
}
}
您可以App
像这样重写返回值:
<Container>
<Child/>
</Container>
// is equal to
React.createElement(
Container,
{},
React.createElement(
Child,
{},
{}
)
)
// which is equal to a React Element object, something like
{
type: Container,
props: {
children: {
type: Child, // |
props: {}, // +---> Take note of this object here
children: {} // |
}
}
}
你也可以Container
像这样重写返回值:
<div onClick={() => this.setState({})}>
{this.props.children}
</div>
// is equal to
React.createElement(
'div',
{onClick: () => this.setState({})},
this.props.children
)
// which is equal to React Element
{
type: 'div',
props: {
children: this.props.children
}
}
现在,this.props.children
与App
返回的 React 元素中包含的内容相同:
{
type: Child,
props: {},
children: {}
}
确切地说,这两个东西在引用上是相同的,这意味着在这两种情况下,它们在内存中都是完全相同的。
现在,无论Container
get 被重新渲染多少次,因为它children
在渲染之间总是引用相同的东西(因为 React Element 是在App
关卡中创建的并且没有理由更改),它们不会被重新渲染。
简而言之,如果 React 元素在引用上 ( ) 等于它在之前渲染中的内容,则React 不会费心再次===
渲染它。
现在,如果您要更改Container
您将拥有:
<div onClick={() => this.setState({})}>
<Child />
</div>
// is equal to
React.createElement(
'div',
{onClick: () => this.setState({})},
React.createElement(
Child,
{},
{}
)
)
// which is equal to
{
type: 'div',
props: {
children: {
type: Child,
props: {},
children: {}
}
}
}
但是在这种情况下,如果您要重新渲染Container
,则必须重新执行
React.createElement(
Child,
{},
{}
)
对于每个渲染。这将导致在渲染之间引用不同的 React 元素,因此 React 实际上也会重新渲染Child
组件,即使最终结果将是相同的。
参考