親コンポーネントが再レンダリングする場合、shouldComponentUpdate()
を実装しない限り、そのすべての子が再レンダリングすることは私の知る限りです。 I 例を作成 これは真実ではないようです。
3つのコンポーネントがあります:_<DynamicParent/>
_、_<StaticParent/>
_、および_<Child/>
_。 _<Parent/>
_コンポーネントは_<Child/>
_のレンダリングを担当しますが、さまざまな方法でレンダリングします。
_<StaticParent/>
_のレンダリング関数は、次のように、実行前に_<Child/>
_を静的に宣言します。
_ <StaticParent>
<Child />
</StaticParent>
_
_<DynamicParent/>
_は、次のように、実行時に_<Child/>
_の受信とレンダリングを動的に処理します。
_ <DynamicParent>
{ this.props.children }
</DynamicParent>
_
_<DynamicParent/>
_と_<StaticParent/>
_の両方には、onClick
リスナーがあり、クリックすると状態が変更されて再レンダリングされます。 _<StaticParent/>
_をクリックすると、それと_<Child/>
_の両方が再レンダリングされることに気付きました。しかし、_<DynamicParent/>
_をクリックすると、親とNOT _<Child/>
_のみが再レンダリングされます。
_<Child/>
_はshouldComponentUpdate()
のない機能コンポーネントなので、なぜ再レンダリングしないのか理解できません。誰かがこれが事実である理由を説明できますか?このユースケースに関連するドキュメントには何も見つかりません。
コンテキストの実際のコードを投稿します。
_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 Texts</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のrenderメソッドが呼び出されるたびにReact.createElement(Child, null)
を呼び出しています。 DynamicParentの場合、子は一度作成され、小道具として渡されます。 _React.createElement
_は純粋な関数なので、おそらくパフォーマンスのためにどこかにメモされているでしょう。
DynamicParentの場合にChildのレンダーを再度実行させるのは、Childの小道具の変更です。たとえば、親の状態が子の小道具として使用された場合、両方のケースで再レンダリングがトリガーされます。
ダン・アブラモフがこの答えを破棄するコメントに現れないことを本当に望んでいます。
主に2つの異なる「子供」がいる原因です。
<Child/>
それらは同じものではありません。最初のものはApplication -> DynamicParent
から渡されたprop
であり、2番目のものはComponent
でレンダリングされたStaticParent
です。個別のレンダリング/ライフサイクル。
含まれている例
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 Application extends React.Component {
render() {
// If you want <Child/> to re-render here
// you need to `setState` for this Application component.
const childEl = <Child />;
return (
<div>
{/*
Clicking this component only logs
the parents render function
*/}
<DynamicParent>
{childEl}
</DynamicParent>
{/*
Clicking this component logs both the
parents and child render functions
*/}
<StaticParent />
</div>
);
}
}