反応のライフサイクルは、コンポーネントの作成、コンポーネントの更新、コンポーネントの破棄の3つの段階に大別されます。また、クラスコンポーネントのみにライフサイクルフック関数があり、関数コンポーネントにはありません。
1.コンポーネントの作成:
図1に、ライフサイクルのフック機能の実行シーケンスを示します。
1.コンストラクター():
データは、this.state割り当てオブジェクトによって初期化できます。
イベントハンドラーのインスタンスをバインドします。
constructor(props) {
super(props);
this.state = {
a: 10,
b: 100
};
this.changeName = this.changeName.bind(this);
}
コンポーネントの作成時に1回だけ実行され、それ以降は実行されません。
2.static getDerivedStateFromProps():
この関数は、初期値をサブコンポーネントとしてコンポーネントに割り当てるために使用され、コンポーネントは独自の状態でデータを変更できます。
通常、判断は関数内で行われます。コンポーネントが独自の状態でデータを変更する場合、親コンポーネントからの小道具のデータは必要ありません。
これは、コンポーネントの作成フェーズと更新フェーズで呼び出されます。
このポインターはなく、2つのパラメーターがあります。最初のパラメーターは親コンポーネントからの小道具のデータであり、2番目のパラメーターはコンポーネントの状態のデータです。
オブジェクトまたはnullを返す必要があります。オブジェクトの場合は、このコンポーネントの状態にマージされます。
static getDerivedStateFromProps(nextProps, prevState) {
if(nextProps.b !== prevState.prevProps.b) {
return {
b: nextProps.b,
prevProps: { b: nextProps.b }
};
}else
return null;
}
3.componentWillMount()|| UNSAFE_componentWillMount():
この関数でsetStateを呼び出しても、追加のレンダリングはトリガーされません。ただし、この関数はコンストラクターで直接実装できます。したがって、この関数は意味がなく、基本的に廃止された状態にあります。
4.render():
レンダリングページの主要部分。一部の操作を実装できますが、jsxオブジェクトを返す必要があります。
コアコードは繰り返し呼び出され、パフォーマンスの最適化を実現するために不要なrender()関数呼び出しの数を減らします。
render() {
// 核心代码,会被反复调用
console.log("render函数运行了");
return (
<div>这是个人中心
<Child b ={this.state.b}></Child>
</div>
);
}
5.componentDIdMount():
コンポーネントがマウントされた後に呼び出されます。コンポーネントの取り付けは、DOMツリーに挿入することです。
この関数では、通常、ajaxリクエストコンポーネントに必要な動的データが送信されます。
ここでsetStateを呼び出すと、render()関数がトリガーされます。
componentDidMount() {
// 组件挂载完毕
let listMain = await http("/category/list/0");
this.setState({ listMain });
this.changeCategory(listMain[0].id);
}
2.コンポーネントの更新:
コンポーネントの更新をトリガーする方法:
1.このコンポーネントはそれ自体でsetStateを呼び出し、再レンダリング(再レンダリング)をトリガーします。
2.親コンポーネントが再レンダリングをトリガーし、子コンポーネントが再レンダリングされます。
3.小道具の変更により、このコンポーネントの再レンダリングがトリガーされます。
1.componentWillReceiveProps()|| UNSAFE_componentWillReceiveProps():
このコンポーネントは、コンポーネントが更新されたときに呼び出されます。通常、次の目的で使用されます。小道具の値が変更された場合、小道具の値の変更に応じて、この関数で対応する操作を実行します。
このコンポーネントは基本的に廃止されました。componentDidUpdateで対応する操作を実行できます。
2.static getDerivedStateFromProps():
操作は、コンポーネントが作成されたときと同じです。詳細については、コンポーネントの作成を参照してください。
3.shouldComponentUpdate():
この関数は、主にreacrのパフォーマンスを最適化するために使用されます。
関数は明示的にtrueまたはfalseを返す必要があります。
2つのパラメーター。最初のパラメーターはnextProps:有効になりそうなprops値で、2番目のパラメーターはnextState:有効になりそうな状態値です。このポインタの現在の値を取得します。
不要な更新を減らすための適切なロジックを記述します。falseを返すと、下向きに実行されないため、レンダリングの数が減り、パフォーマンスが最適化されます。
shouldComponentUpdate(nextProps){
console.log("child组件的shouldComponentUpdate运行了");
return this.props.b !== nextProps.b;
}
// 如果不写默认返回true
レンダリング最適化のコードは次のとおりです。
shouldComponentUpdate(nextProps){
let keys = Object.keys(nextProps);
for(let i = 0; i < keys.length; i++) {
if(this.props[keys[i]] !== nextProps[keys[i]] ) return true;
}
return false;
}
これは、reactのpureComponentから継承されたクラスコンポーネントのデフォルトのshouldComponentUpdate()関数と同等です。
import React, {PureComponent} from 'react';
class Child extends PureComponent {}
PureComponentは、小道具のすべてのプロパティを比較し、最初に現在のコンポーネントを再レンダリングする必要があるかどうかを判断します。
ただし、PureComponentは、プロパティ値の単純な「浅い比較」のみを実行します。
値型の場合、浅い比較で問題ありません。参照型の場合、メモリ内のアドレスが同じであるかどうかのみを比較し、詳細レベルの比較は実行しません。
異なるアドレスと同じコンテンツを持つ参照型が渡された場合、PureComponentは詳細な比較を実行できません。
ユースケース:コンポーネントがクラスコンポーネントであることがわかっていて、このクラスコンポーネントをパフォーマンスのために最適化する必要がある場合。
最大の落とし穴:親コンポーネントが参照型のデータを子コンポーネントに渡す場合、値を渡すときに直接バインドすることはできません。例えば:
// 错误写法
<Child b ={this.state.b} changeName={this.changeName.bind(this)}></Child>
// 正确写法
changeName = () => {};
<Child b ={this.state.b} changeName={this.changeName}></Child>
4.componentWillUpdate()|| UNSAFE_componentWillUpdate():
このメソッドは非推奨になりました。componentDidUpdate()を使用して、この関数の関数を置き換えることができます。
dom情報を読み取る必要がある場合は、代わりにgetSnapshotBeforeUpdateを使用できます。
componentWillUpdate(){
// 基本废弃,一般不用了。改名了UNSAFE_componentWillUpdate
console.log("componentWillUpdate函数运行了");
}
5.render():
更新段階のレンダリングでは、コンポーネントのdomノードを新しいデータに従ってレンダリングできます。domノードは前回と比較され、変更するさまざまなノードが見つかります。すべてのDOMノードが再レンダリングされるわけではありません。
6.getSnapshotBeforeUpdate():
通常、この関数でいくつかのdom操作を実行します。スクロール位置を記録します。
例:スクロール可能なページ。突然更新した後、この関数にその位置を記録し、それをcomponentDidUpdate()関数に渡す必要があります。更新が終了すると、その位置に戻ることができます。
2つのパラメータがあります:prevProps、prevState、その内容は上記と同じです。
値を返す必要があります
getSnapshotBeforeUpdate(prevProps, prevState){
return { y: 50 }
}
componentDidUpdate(prevProps, prevState, snapshot){
console.log(snapshot) // { y: 50 }
}
7.componentDidUpdate():
この機能は、主に更新が完了したときに実行されます。
2つのパラメーターがあります。最初のパラメーターはprevPropsで、更新前のprops値であり、2番目のパラメーターは更新前の状態の値を表します。現在の値はthis.propsです。3番目のパラメーターは、getSnapshotBeforeUpdate()によって渡されるデータです。
実装は、vueでの監視の監視に似ています。更新前後のデータを比較する。
この関数は、最新の状態に対応するdomが更新されたことを示しているため、最新のdomでいくつかのカスタム操作を実行できます。
// 模拟vue中的watch监听
componentDidUpdate(prevProps,prevState) {
if(prevState.a !== this.state.a) {
console.log("a变量");
}
}
// 对最新的dom做些自定义操作
// 例如使用插件监听滚动
3.コンポーネントの破壊:
使用されなくなったコンポーネント、または長期間使用されていないコンポーネントは、破棄する必要があります。
1.componentWillUnmount():
この関数は、主に関連するメモリスペースとリソースを解放するために使用されます。
// 组件销毁
componentWillUnmount() {
// 释放当前组件相关的内存和资源
console.log("componentWillUnmount运行了")
}
上記はreactのライフサイクルのフック機能であり、さまざまな機能を通じてさまざまな機能を実現できます。
親コンポーネントと子コンポーネントのライフサイクルフック関数の実行シーケンスは次のとおりです。
親コンポーネントのコンストラクター関数とレンダリング関数は子コンポーネントの前に実行され、子コンポーネントのcomponentDidMountとcomponentDidUpdateは親コンポーネントの前に実行されます。