React,Vue 和 Angular 的流行,讓「生命週期」這個名詞經常出如今前端們的口中,以致於面試中最多見的一個問題也是:javascript
介紹下React, Vue的生命週期以及使用方法?前端
聽起來高大上的「生命週期」,其實也就是一些普通的方法,只是在不一樣的時期傳參調用它們而已。咱們能夠照着React的生命週期,本身模擬一個簡單的類,並讓這個類擁有一些生命週期鉤子java
咱們但願實現一個State
類,這個類擁有如下方法和生命週期:面試
方法:ui
生命週期:this
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的面向對象spa
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
合併code
willStateUpdate
是state
狀態更新前調用的。所以只要在合併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
返回true時,才更新state
。所以在合併state
前,還要調用shouldStateUpdate
生命週期
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 }); // 沒有更新
複製代碼
懂了willStateUpdate
也就知道didStateUpdate
如何實現了
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
類了!