JavaScript實現自定義的生命週期

React,Vue 和 Angular 的流行,讓「生命週期」這個名詞經常出如今前端們的口中,以致於面試中最多見的一個問題也是:javascript

介紹下React, Vue的生命週期以及使用方法?

聽起來高大上的「生命週期」,其實也就是一些普通的方法,只是在不一樣的時期傳參調用它們而已。咱們能夠照着React的生命週期,本身模擬一個簡單的類,並讓這個類擁有一些生命週期鉤子前端

咱們但願實現一個State類,這個類擁有如下方法和生命週期:java

方法:面試

  • setState

生命週期:this

  • willStateUpdate (nextState): 狀態將要改變
  • shouldStateUpdate (nextState): 是否要讓狀態改變,只有返回true纔會改變狀態
  • didStateUpdate (prevState): 狀態改變後(要是 shouldStateUpdate 返回的不爲true則不會調用)
class User extends State {
  constructor(name) {
    super();
    this.state = { name }
  }

  willStateUpdate(nextState) {
    console.log('willStateUpdate', nextState);
  }

  shouldStateUpdate(nextState) {
    console.log('shouldStateUpdate', nextState);
    if (nextState.name === this.state.name) {
      return false;
    }

    return true;
  }

  didStateUpdate(prevState) {
    console.log('didStateUpdate', prevState);
  }
}

const user = new User('deepred');

user.setState({ name: 'hentai' });

首先,你須要知道JavaScript的面向對象基礎知識,若是還不是很瞭解,能夠先看下這篇文章JavaScript的面向對象code

setState的實現

class State {
  constructor() {
    this.state = {};
  }

  setState(nextState) {
    const preState = this.state;
    this.state = {
      ...preState,
      ...nextState,
    };
  }
}
class User extends State {
  constructor(name) {
    super();
    this.state = {
      name
    }
  }
}


const user = new User('tc');

user.setState({age: 10}); // {name: 'tc', age: 10}

在React中,setState方法只會改變特定屬性的值,所以,咱們須要在方法裏用一個變量preState保留以前的state,而後經過展開運算符,將新舊state合併對象

willStateUpdate的實現

willStateUpdatestate狀態更新前調用的。所以只要在合併state前調用willStateUpdate就行生命週期

class State {
  constructor() {
    this.state = {};
  }

  setState(nextState) {
    // 更新前調用willStateUpdate
    this.willStateUpdate(nextState);
    const preState = this.state;
    this.state = {
      ...preState,
      ...nextState,
    };
  }

  willStateUpdate() {
    // 默認啥也不作
  }

}
class User extends State {
  constructor(name) {
    super();
    this.state = {
      name
    }
  }

  // 覆蓋父級同名方法
  willStateUpdate(nextState) {
    console.log('willStateUpdate', nextState);
  }
}

const user = new User('tc');

user.setState({age: 10}); // {name: 'tc', age: 10}

shouldStateUpdate的實現

咱們規定只有shouldStateUpdate返回true時,才更新state。所以在合併state前,還要調用shouldStateUpdateip

class State {
  constructor() {
    this.state = {};
  }

  setState(nextState) {
    this.willStateUpdate(nextState);
    const update = this.shouldStateUpdate(nextState);
    if (update) {
      const preState = this.state;
      this.state = {
        ...preState,
        ...nextState,
      };
    }
  }

  willStateUpdate() {
    // 默認啥也不作
  }

  shouldStateUpdate() {
    // 默認返回true,一直都是更新
    return true;
  }

}
class User extends State {
  constructor(name) {
    super();
    this.state = {
      name
    }
  }

  // 覆蓋父級同名方法
  willStateUpdate(nextState) {
    console.log('willStateUpdate', nextState);
  }

  // 自定義什麼時候更新
  shouldStateUpdate(nextState) {
    if (nextState.name === this.state.name) {
      return false;
    }

    return true;
  }
}


const user = new User('tc');

user.setState({ age: 10 }); // {name: 'tc', age: 10}

user.setState({ name: 'tc', age: 11 }); // 沒有更新

didStateUpdate的實現

懂了willStateUpdate也就知道didStateUpdate如何實現了get

class State {
  constructor() {
    this.state = {};
  }

  setState(nextState) {
    this.willStateUpdate(nextState);
    const update = this.shouldStateUpdate(nextState);
    if (update) {
      const preState = this.state;
      this.state = {
        ...preState,
        ...nextState,
      };
      this.didStateUpdate(preState);
    }
  }

  willStateUpdate() {
    // 默認啥也不作
  }

  didStateUpdate() {
    // 默認啥也不作
  }

  shouldStateUpdate() {
    // 默認返回true,一直都是更新
    return true;
  }

}
class User extends State {
  constructor(name) {
    super();
    this.state = {
      name
    }
  }

  // 覆蓋父級同名方法
  willStateUpdate(nextState) {
    console.log('willStateUpdate', nextState);
  }

  // 覆蓋父級同名方法
  didStateUpdate(preState) {
    console.log('didStateUpdate', preState);
  }

  shouldStateUpdate(nextState) {
    console.log('shouldStateUpdate', nextState);
    if (nextState.name === this.state.name) {
      return false;
    }

    return true;
  }
}


const user = new User('tc');

user.setState({ age: 10 }); 

user.setState({ name: 'tc', age: 11 });

經過幾十行的代碼,咱們就已經實現了一個自帶生命週期的State類了!

相關文章
相關標籤/搜索