React双戳,Vue 和 Angular 的流行,讓“生命周期”這個(gè)名詞常常出現(xiàn)在前端們的口中糜芳,以至于面試中最常見的一個(gè)問題也是:
介紹下React, Vue的生命周期以及使用方法?
聽起來高大上的“生命周期”拣技,其實(shí)也就是一些普通的方法,只是在不同的時(shí)期傳參調(diào)用它們而已耍目。我們可以照著React的生命周期膏斤,自己模擬一個(gè)簡(jiǎn)單的類,并讓這個(gè)類擁有一些生命周期鉤子
我們希望實(shí)現(xiàn)一個(gè)State類邪驮,這個(gè)類擁有以下方法和生命周期:
方法:
setState
生命周期:
willStateUpdate (nextState): 狀態(tài)將要改變
shouldStateUpdate (nextState): 是否要讓狀態(tài)改變莫辨,只有返回true才會(huì)改變狀態(tài)
didStateUpdate (prevState): 狀態(tài)改變后(要是 shouldStateUpdate 返回的不為true則不會(huì)調(diào)用)
<!-- more -->
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的面向?qū)ο蠡A(chǔ)知識(shí)
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方法只會(huì)改變特定屬性的值沮榜,因此盘榨,我們需要在方法里用一個(gè)變量preState保留之前的state,然后通過展開運(yùn)算符蟆融,將新舊state合并
willStateUpdate的實(shí)現(xiàn)
willStateUpdate是state狀態(tài)更新前調(diào)用的草巡。因此只要在合并state前調(diào)用willStateUpdate就行
class State {
? constructor() {
? ? this.state = {};
? }
? setState(nextState) {
? ? // 更新前調(diào)用willStateUpdate
? ? this.willStateUpdate(nextState);
? ? const preState = this.state;
? ? this.state = {
? ? ? ...preState,
? ? ? ...nextState,
? ? };
? }
? willStateUpdate() {
? ? // 默認(rèn)啥也不做
? }
}
class User extends State {
? constructor(name) {
? ? super();
? ? this.state = {
? ? ? name
? ? }
? }
? // 覆蓋父級(jí)同名方法
? willStateUpdate(nextState) {
? ? console.log('willStateUpdate', nextState);
? }
}
const user = new User('tc');
user.setState({age: 10}); // {name: 'tc', age: 10}
shouldStateUpdate的實(shí)現(xiàn)
我們規(guī)定只有shouldStateUpdate返回true時(shí),才更新state型酥。因此在合并state前山憨,還要調(diào)用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() {
? ? // 默認(rèn)啥也不做
? }
? shouldStateUpdate() {
? ? // 默認(rèn)返回true,一直都是更新
? ? return true;
? }
}
class User extends State {
? constructor(name) {
? ? super();
? ? this.state = {
? ? ? name
? ? }
? }
? // 覆蓋父級(jí)同名方法
? willStateUpdate(nextState) {
? ? console.log('willStateUpdate', nextState);
? }
? // 自定義何時(shí)更新
? 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的實(shí)現(xiàn)
懂了willStateUpdate也就知道didStateUpdate如何實(shí)現(xiàn)了
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() {
? ? // 默認(rèn)啥也不做
? }
? didStateUpdate() {
? ? // 默認(rèn)啥也不做
? }
? shouldStateUpdate() {
? ? // 默認(rèn)返回true弥喉,一直都是更新
? ? return true;
? }
}
class User extends State {
? constructor(name) {
? ? super();
? ? this.state = {
? ? ? name
? ? }
? }
? // 覆蓋父級(jí)同名方法
? willStateUpdate(nextState) {
? ? console.log('willStateUpdate', nextState);
? }
? // 覆蓋父級(jí)同名方法
? 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 });
通過幾十行的代碼郁竟,我們就已經(jīng)實(shí)現(xiàn)了一個(gè)自帶生命周期的State類了!