序文
Reactのライフサイクルは、仕事で常に非常に重要です。必要な期間内に必要なことを行う必要があることがよくあります。Reactでは、ライフサイクルは、初期化(初期化)、マウント(マウント)、更新フェーズとアンマウントフェーズでは、各フェーズで異なるライフサイクル関数が呼び出されます。もちろん、reactバージョンのアップデートに伴い、相対的な変更がありますので、ここでまとめを参照してみましょう。
ほとんどのチームは必ずしもフォローアップしてバージョン16にアップグレードするわけではないため、16が以前の変更に基づいていることは言うまでもなく、16より前のライフサイクルをマスターする必要があります。
初期化
つまり、次のコードのクラスの構築メソッド(constructor())です。Testクラスはreact Componentの基本クラスを継承し、reactの基本クラスも継承するため、render()やlifeなどのメソッドはサイクルを使用できます。これは、機能コンポーネントがこれらのメソッドを使用できない理由も示しています。super(props)は、基本クラスの構築メソッド(constructor())を呼び出し、親コンポーネントの小道具を子コンポーネントに挿入し、子コンポーネントを読み取るために使用されます(コンポーネント内の小道具は読み取り専用であり、不変であり、状態は可変です)。コンストラクター()は、this.stateの初期コンテンツの定義など、一部のコンポーネントを初期化するために使用されます。
注:
constructor
ライフサイクル機能としてはカウントされません。constructor
これをコンストラクターと呼びます。これはES6の基本構文です。ライフサイクル関数と同じ性質を持っていますが、ライフサイクル関数とは言えません。しかし、あなたはそれをあなたの心のライフサイクル機能として考えなければなりません。私は個人的にそれInitialization
をReactの段階と見なし、プロパティ(小道具)と状態(状態)を定義します。
import React, {
Component } from 'react'
class Test extends Component {
constructor(props) {
super(props)
}
}
第2段階での取り付け
componentWillMount
:コンポーネントがページにマウントされようとしているときに実行します。
コンポーネントがDOMにマウントされる前に呼び出され、一度だけ呼び出されます。ここでthis.setStateを呼び出しても、コンポーネントは再レンダリングされません。ここに記述されたコンテンツをコンストラクター()に進めることもできるため、プロジェクトは使用量が非常に少なくなります。
render
:ページの状態または小道具が変更されたときに実行します。
コンポーネントの小道具と状態(2つの再送信と再割り当てなしで、引数が変更されるかどうかにかかわらず、コンポーネントが再レンダリングされる可能性があります)に従って、React要素(コンポーネント、つまりUIを説明する)を返します。コンポーネントの実際のレンダリングを担当し、React自体がこの要素に基づいてページDOMをレンダリングします。Renderは純粋関数です(純粋関数:関数の戻り結果はそのパラメーターにのみ依存します。関数の実行に副作用はありません)。This.setStateはその中で実行できず、次のような副作用が発生します。コンポーネントの状態を変更します。
componentDidMount
:コンポーネントがマウントされたときに実行されます。
コンポーネントがDOMにマウントされた後に呼び出され、1回だけ呼び出されます
export default class App extends Component {
componentWillMount () {
console.log('componentWillMount----组件将要挂载到页面的时刻')
}
render() {
console.log('render---组件挂载中.......')
return (
<div>
<TodoList/>
<ReduxTodoList/>
</div>
)
}
componentDidMount () {
console.log('componentDidMount----组件挂载完成的时刻执行')
}
}
印刷結果:
componentWillMount----组件将要挂载到页面的时刻执行
render----开始挂载渲染
componentDidMount----组件挂载完成的时刻执行
这就是挂载阶段的生命周期的执行顺序,当然他跟书写顺序没有关系
注:
componentWillMount
そして、componentDidMount
これら二つのライフサイクル関数はのみ、ページが更新されたときに一度実行され、レンダリング機能は、長い状態や小道具の変化があったとしてとして実行され、この初心者が注意を払う必要があります。
3つの更新段階の更新
この段階はもっと複雑な段階です。上の図から、コンポーネントの更新には2つのタイプがあることがわかります。Reactコンポーネントの更新メカニズムを明確にする必要があります。setStateによって引き起こされた状態の更新、または親コンポーネントの再レンダリングによって引き起こされたpropsの更新。更新された状態とpropsは、前のコンポーネントと比較して変更があるかどうかに関係なく、子コンポーネントの再レンダリングを引き起こします。
-
shouldComponentUpdate
コンポーネントが更新される前に、自動的に実行されます。ブール結果を返す必要があります。戻り値が必要です。ここでは、trueを直接返します(実際の開発では、これは非常に役立ち、パフォーマンスの問題を効果的に解決できます。 )、falseを返すと、コンポーネントは更新されません。簡単に言うと、trueを返す場合はコンポーネントの更新に同意し、falseを返す場合はコンポーネントの更新に反対します。このメソッドは、現在のコンポーネントのnextProps、nextStateとthis.props、this.stateを比較します。trueを返すと、現在のコンポーネントは引き続き更新プロセスを実行し、falseを返すと、現在のコンポーネントの更新を停止します。これを使用できます。コンポーネントの不要なレンダリングを減らし、コンポーネントのパフォーマンスを最適化します。 -
componentWillUpdate
コンポーネントが更新される前、shouldComponenUpdate
実行された後、ただしshouldComponenUpdate
戻り値がfalseの場合、コンポーネントの更新は反対され、この関数は実行されません。 -
componentDidUpdate
コンポーネントが更新された後に実行され、コンポーネント更新の最後の部分です。
export default class App extends Component {
shouldComponentUpdate () {
console.log ('1.shouldComponentUpdate----组件更新之前')
return true
}
componentWillUpdate () {
console.log ('2.componentWillUpdate---组件更新前,shouldComponentUpdate函数之后执行 ')
}
render() {
console.log('3.render---组件挂载渲染.......')
return (
<div>
<TodoList/>
<ReduxTodoList/>
</div>
)
}
componentDidUpdate () {
console.log('componentDidUpdate----组件更新完成的时刻执行')
}
}
結果と実行順序を印刷する
1-shouldComponentUpdate---组件发生改变前执行
2-componentWillUpdate---组件更新前,shouldComponentUpdate函数之后执行
3-render----开始挂载渲染
4-componentDidUpdate----组件更新之后执行
- では、上の図は
componentWillReceiveProps
いつ実行されるのでしょうか?実際、子コンポーネントは親コンポーネントから渡されたパラメーターを受け取り、親コンポーネントのレンダリング関数が再度実行され、このライフサイクルが実行されます。
注:
使用したcomponentWillReceiveProps
コンポーネントが初めてDomに存在する場合、関数は実行されません。
すでにDomに存在する場合は、関数が実行されます。
親コンポーネントから渡された小道具によってコンポーネントが更新されようとしているときに呼び出されます。このメソッドは、現在の親コンポーネントからコンポーネントに渡された最新の小道具ステータスデータを参照するパラメーターを受け入れます。このライフサイクルメソッドでは、nextPropsとthis.propsの新旧の小道具の値を比較することで小道具が変更されたかどうかを確認し、データ処理ロジックを順番に実行します。
アンマウント
この段階でのライフサイクル関数は1つだけです。componentWillUnmount
このメソッドは、コンポーネントがアンインストールされる前に呼び出されます。ここでは、コンポーネントで使用されているタイマーのクリア、componentDidMount
手動で作成されたDOM要素のクリア、イベントのバインド解除など、いくつかのクリーニング作業を実行できます。。メモリリークの発生を回避する
ライフサイクル関数を使用する最適化ページを要約します。
componentDidMount
ライフサイクル関数でajaxをリクエストします。これは、componentDidMount関数で実行することをお勧めします。これは、レンダリングで実行されるため、ループレンダリングなど、多くの問題が発生します。componentWillMountで実行すると、次のようになります。 RNを使用すると競合します。したがって、componentDidMount関数でajaxリクエストを行うことを強くお勧めします。- 親コンポーネントが更新されて子コンポーネントに渡されると、とにかく長所が変更され、子コンポーネントのレンダリング機能が常にトリガーされ、パフォーマンスの問題が発生します。通常、更新フェーズで発生する可能性があるため、shouldComponentUpdateを使用します。
shouldComponentUpdate(nextProps,nextState){
if(nextProps.content !== this.props.content){
return true
}else{
return false
}
}
Reactv16.4のライフサイクル
変更理由
非同期レンダリングをオンにすると、レンダリング機能の前のすべての機能が複数回実行される可能性があるため、React v16でファイバーを起動した後のライフサイクル(React v16.0より前)は適切ではないことがわかりました。
レンダリング前に実行された元の(React v16.0より前の)ライフサイクルは何ですか?
- componentWillMount
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
開発者が非同期レンダリングを開き、上記のレンダリングの前に実行されたライフサイクルメソッドを使用してA JAXリクエストを行うと、AJAXは不必要に複数回呼び出されます。。。明らかに、私たちが期待した結果ではありません。さらに、componentWillMountでAJAXを開始すると、結果がどれほど速く得られても、最初のレンダリングに追いつくことができず、componentWillMountもサーバー側のレンダリングのために呼び出されます(もちろん、これは期待される結果である可能性があります) )。このようなIO操作は、componentDidMountでより適しています。
潘はそうshouldComponentUpdateに加えて、これを使用しない説得開発の効果よりも良くなることはできませんが、レンダリング機能の前に他のすべての機能は、( 、componentWillMount
、componentWillReceiveProps
)componentWillUpdate
されているgetDerivedStateFromProps
置き換え。
つまり、静的関数を使用getDerivedStateFromProps
して、廃止されたいくつかのライフサイクル関数を置き換えます。これにより、開発者はレンダリング前に副作用のない操作のみを実行するようになり、実行できる操作は、に基づいて新しい状態を決定することに限定されます。小道具と状態
2つの新しいライフサイクル機能が新たに導入されました。
1. getDerivedStateFromProps
getDerivedStateFromPropsは元々(React v16.3で)作成および更新されるだけです(親コンポーネントによってトリガーされる部分)。つまり、親コンポーネントによってトリガーされることはなく、getDerivedStateFromPropsは呼び出されません(独自のsetStateトリガーやforceUpdate
は、React v16.4でこれを修正するために、少し混乱を引き起こします。これにより、getDerivedStateFromPropsは、Mounting
またはUpdating
、更新が原因で発生した原因に関係なく、特にFigure Reactv16.4のライフサイクルを確認するためにすべてが呼び出されます。
getDerivedStateFromProps(props、state)は、コンポーネントの作成時と
更新時に、renderメソッドの前に呼び出されます。状態を更新するにはオブジェクトを返すか、何も更新しない場合はnullを返す必要があります。
親コンポーネントが現在のコンポーネントのレンダリングをトリガーするたびに、getDerivedStateFromPropsが呼び出されるため、新しい小道具と以前の状態に基づいて新しい状態を調整する機会があります。比較的純粋で副作用のない3つの非推奨のライフサイクル関数に入れると、getDerivedStateFromPropsに移動できます。残念ながらAJAXのようなことをした場合は、最初になぜそれを行ったのかを最初に考えなければなりません。次に、componentDidMountに移動するか、componentDidUpdateに移動します。現在、非推奨の3つのライフサイクル関数を使用すると、開発モードで赤い警告が表示され、UNSAFE_プレフィックスを使用する必要があります。メジャーバージョンアップデートがリリースされると破棄される可能性があるため、幸運にも諦めた開発者はそれを使用します。
2. getSnapshotBeforeUpdate
getSnapshotBeforeUpdate()は、レンダリング後にDOMを読み取ることはできるが使用できない場合に、呼び出されます。これにより、コンポーネントは、変更される前にDOMからいくつかの情報(スクロール位置など)をキャプチャできます。このライフサイクルによって返される値はすべて、パラメーターとしてcomponentDidUpdate()に渡されます。
公式ウェブサイトに掲載されている例:
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
getSnapshotBeforeUpdate(prevProps, prevState) {
//我们是否要添加新的 items 到列表?
// 捕捉滚动位置,以便我们可以稍后调整滚动.
if (prevProps.list.length < this.props.list.length) {
const list = this.listRef.current;
return list.scrollHeight - list.scrollTop;
}
return null;
}
componentDidUpdate(prevProps, prevState, snapshot) {
//如果我们有snapshot值, 我们已经添加了 新的items.
// 调整滚动以至于这些新的items 不会将旧items推出视图。
// (这边的snapshot是 getSnapshotBeforeUpdate方法的返回值)
if (snapshot !== null) {
const list = this.listRef.current;
list.scrollTop = list.scrollHeight - snapshot;
}
}
render() {
return (
<div ref={
this.listRef}>{
/* ...contents... */}</div>
);
}
}
注:
getDerivedStateFromProps、getSnapshotBeforeUpdate、および非推奨のライフサイクル関数の新しいライフサイクルAPIを同時に使用すると、非推奨のライフサイクル関数は直接無視され、時間内に実行されません。