此.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.childChildJSX中的组件评估,所以不确定。

<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函数,并且应重新渲染所有子元素。

您似乎非常接近了解这里发生的情况。

到目前为止,你是正确的,因为Containerrender执行,因此必须从它返回的组件调用自己的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.childrenApp返回的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

回到顶部