生命周期
我們先來看下React16.0前后生命周期變化的圖片
生命周期圖譜:http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
? 過時生命周期:
① componentWillMount
② componentWillReceiveProps
③ componentWillUpdate
? 即將過時生命周期:(在新代碼中我們應(yīng)該避免使用它們)
① UNSAFE_componentWillMount
② UNSAFE_componentWillReceivePorps
③ UNSAFE_componentWillUpdate
? 新增生命周期
① getDerivedStateFromProps
②?getSnapShotBeforeUpdate
③ getDerivedStateFromError
④ componentDidCatch
老生命周期我就不贅述了,下邊我歸納下我對幾個新生命周期用法的理解
①?static getDerivedStateFromProps(nextProps, prevState)
○ 什么時候調(diào)用凑队?
這個方法會在調(diào)用 render 方法之前調(diào)用则果,并且在初始掛載及后續(xù)更新時都會被調(diào)用。它應(yīng)返回一個對象來更新 state漩氨,如果返回 null 則不更新任何內(nèi)容西壮。
○ 返回值
返回值是必須的,它應(yīng)該是一個對象叫惊,用于更新state; 如果返回值為null款青,state不更新。
○ 主要用途霍狰?
這個生命周期函數(shù)是為了替代componentWillReceiveProps存在的抡草,所以在你需要使用componentWillReceiveProps的時候饰及,就可以考慮使用getDerivedStateFromProps來進(jìn)行替代。主要是將新的props更新到state上
特別說明:
它是靜態(tài)方法康震,所以它沒有this(實例對象無法訪問)旋炒,只能通過類名訪問。
看下邊例子就明白了签杈!
class Child extends Component {
? ? constructor(props) {
? ? ? ? super(props);
? ? ? ? this.state= {
? ? ? ? ? ? info: props.info || "hello world"
? ? ? ? }
}
? ? static getDerivedStateFromProps(nextProps, prevState) {
? ? ? ? if (nextProps.info!== prevState.info) {
? ? ? ? ? ? return ({
? ? ? ? ? ? ? ? info: nextProps.info
????????????})
????????}
? ? ? ? return null;
? ? }
? ? render() {
? ? ? ? return (
? ? ? ? ? ? <p>{this.state.info}</p>
? ? ? ? ????????????)
? ? ? ?}
?}
class App extends Component {
? ? constructor(props) {
? ? ? ? super(props);
? ? ? ? this.state= {
? ? ? ? ? ? childInfo: "Hello world"
? ? ? ? }
????}
? ? clickHandler = () => {
? ? ? ? this.setState({
? ? ? ? ? ? childInfo: "Changed world"
? ? ? ? })
? ? };
? ? render() {
? ? ? ? return (
? ? ? ? ? ? <>
? ? ? ? ? ? ? ? <Child info={this.state.childInfo}/>
? ? ? ? ? ? ? ? <button onClick={this.clickHandler}>Click Me</button>
? ? ? ? ????</>
? ? ? ? );
? ? }
}
②?getSnapshotBeforeUpdate(prevProps, prevState)
○ 什么時候調(diào)用瘫镇?
getSnapshotBeforeUpdate()?在最近一次渲染輸出(提交到 DOM 節(jié)點)之前調(diào)用。
○ 返回值
應(yīng)返回 snapshot 的值(或?null)
○ 有什么用途答姥?
它使得組件能在發(fā)生更改之前從 DOM 中捕獲一些信息(例如铣除,滾動位置)。此生命周期的任何返回值將作為參數(shù)傳遞給?componentDidUpdate()鹦付。
此用法并不常見尚粘,但它可能出現(xiàn)在 UI 處理中,如需要以特殊方式處理滾動位置的聊天線程等敲长。
③ static getDerivedStateFromError(error)
○ 什么時候調(diào)用郎嫁?
此生命周期會在渲染階段后代組件拋出錯誤后被調(diào)用,因此不允許出現(xiàn)副作用祈噪。
○ 返回值
它將拋出的錯誤作為參數(shù)泽铛,并返回一個值以更新 state
○ 有什么用途?
主要用于封裝錯誤邊界用辑鲤,收集錯誤信息并做對應(yīng)處理盔腔。
以下為具體用法用例
class ErrorBoundary extends React.Component {
? ? constructor(props) {
? ? ? ? super(props);
? ? ? ? this.state= {hasError: false};
? ? }
? ? static getDerivedStateFromError(error) {
? ? ? ? // 更新 state 使下一次渲染可以顯降級UI
? ? ? ? return {hasError: true};
? ? }
? ? render() {
? ? ? ? if (this.state.hasError) {
? ? ? ? ? ? // 你可以渲染任何自定義的降級UI
? ? ? ? ? ? return <h1>Something went wrong.</h1>;
? ? ? ? }
? ? ? ? return this.props.children;
? ? }
}
然后你可以將它作為一個常規(guī)組件去使用:
<ErrorBoundary>
? ? <div>Hello world</div>
</ErrorBoundary>
④ componentDidCatch(error, info)
○ 什么時候調(diào)用?
此生命周期會在“提交”階段后代組件拋出錯誤后被調(diào)用月褥,因此允許執(zhí)行副作用弛随。
○ 參數(shù)
error?—— 拋出的錯誤。
info?—— 帶有?componentStack?key 的對象宁赤,其中包含有關(guān)組件引發(fā)錯誤的棧信息舀透。
○ 返回值
它將拋出的錯誤作為參數(shù),并返回一個值以更新 state
○ 有什么用途决左?
主要用于封裝錯誤邊界用愕够,收集錯誤信息并做對應(yīng)處理。
用例如下:
class ErrorBoundary extends React.Component {
? ? constructor(props) {
? ? ? ? super(props);
? ? ? ? this.state= { hasError: false };
? ? }
? ? static getDerivedStateFromError(error) {
? ? ? ? // 更新 state 使下一次渲染可以顯示降級UI
? ? ? ? return { hasError: true };
? ? }
? ? componentDidCatch(error, info) {
? ? ? ? // "組件堆棧" 例子:
//? in ComponentThatThrows (created by App)
//? in ErrorBoundary (created by App)
//? in div (created by App)
//? in App
? ? ? ? logComponentStackToMyService(info.componentStack);
? ? }
? ? render() {
? ? ? ? if (this.state.hasError) {
? ? ? ? ? ? // 你可以渲染任何自定義的降級UI
? ? ? ? ? ? return <h1>Something went wrong.</h1>;
? ? ? ? }
? ? ? ? return this.props.children;
? ? }
}
特別注意:
如果發(fā)生錯誤哆窿,你可以通過調(diào)用?setState?使用?componentDidCatch()?渲染降級 UI链烈,但在未來的版本中將不推薦這樣做。 可以使用靜態(tài)?getDerivedStateFromError()?來處理降級渲染挚躯。
結(jié)論:對于新生命周期③和④作用基本是一致的强衡,都是用于封裝錯誤邊界,收集邊界下后代組件構(gòu)造函數(shù)中發(fā)生的錯誤信息并作出對應(yīng)處理码荔。不同的是調(diào)用時間和返回參數(shù)漩勤。