此.props.children不会在父状态更改时重新呈现
我有一段代码
import React, {Component} from 'react';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>
}
}
export default App;
单击“ Hi”消息时,仅Container
组件会继续重新渲染,而Child
组件不会重新渲染。
我想说,由于它是Container
组件的一个属性而不会发生,但是仍然会this.props.child
被Child
JSX中的组件评估,所以不确定。
<div onClick={() => this.setState({})}> {this.props.children}
</div>
完整示例https://codesandbox.io/s/529lq0rv2n(检查控制台日志)
回答:
这个问题已经很老了,但是由于您似乎没有得到满意的答案,因此我也会尝试一下。
正如您自己观察到的,改变
// Scenario A<div onClick={() => this.setState({})}>
{this.props.children}
</div>
至
// Scenario B<div onClick={() => this.setState({})}>
<Child />
</div>
事实上,最终会
容器渲染
儿童渲染
在控制台中,每次单击。
现在,引用你
据我所知,如果触发了setState(),则将调用Container组件的render函数,并且应重新渲染所有子元素。
您似乎非常接近了解这里发生的情况。
到目前为止,你是正确的,因为Container
的render
执行,因此必须从它返回的组件调用自己的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 Element中包含的内容相同:
{ type: Child,
props: {},
children: {}
}
确切地说,这两种情况在 引用上 是相同的,这意味着在两种情况下,它们在内存中都是完全相同的。
现在,无论Container
重新渲染多少次,由于渲染children
之间总是参照相同的事物(因为React
Element是在App
关卡中创建的,并且没有理由更改),因此它们不会重新渲染。
简而言之, ,
现在,如果要更改,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元素在渲染之间具有引用上的差异,因此Child
即使最终结果相同,React也会实际上也重新渲染组件。
参考
以上是 此.props.children不会在父状态更改时重新呈现 的全部内容, 来源链接: utcz.com/qa/410180.html