1. 程式人生 > >es6學習1: 模擬react Comopnent類的實現

es6學習1: 模擬react Comopnent類的實現

開始系統學習es6, 按自己的理解簡單模擬個react的Component類和生命週期思維,  見證自己的成長, 初學, 寫著娛樂, 勿噴  T.T

test.js

import mm from '../util/util.js';


class Component{
    constructor(props) {
        this.props =  {}; // 注入的history等
        this.props = Object.assign(this.props, props || {});
        this.state = {};
        
this.loadComponent(); } setState(obj, fallBack){ // 判斷是否需要重新整理虛擬dom if (this.shouldComponentUpdate(obj)) { this.componentUpdate(); Object.assign(this.state,obj); this.componentDidUpdate(); this.loadComponent(); }
// 呼叫回撥函式 typeof fallBack === 'function' && fallBack(); } loadComponent() { this.componentWillUMount(); this.loadProps(); this.componentDidUMount(); } loadProps(){} flushVdom(){} // 模擬生命週期函式 shouldComponentUpdate(obj){ console.log(
"shouldComponentUpdate"); // 物件深拷貝 let stateCopy = mm.objDeepCopy(this.state); // 合併物件 let objResult = Object.assign(stateCopy, (obj || {})); // 將setstate的值和state的值合併看和原state的值是否相等 if (mm.isEqual(objResult,this.state)) { // 相等則不重新整理元件 console.log("值相等: 不重新整理虛擬dom"); return false; } console.log("值不等, 重新整理虛擬dom"); this.flushVdom(); // 不相等重新整理元件 return true; } componentUpdate(){ console.log('componentWillUpdate'); } componentDidUpdate(){ console.log('componentDidUpdate'); } componentWillUMount(){ console.log('componentWillMount'); } componentDidUMount(){ console.log('componentDidMount'); } } class Test2 extends Component{ constructor(props){ super(props); } render(){ this.setState( {}, ()=>(console.log("setState後的回撥方法...")) ); return(`<div>我是得到的標籤</div>`) } } // 模擬呼叫 console.log(new Test2().render());

工具類 util.js (物件深拷貝及isEquels方法)

let mm = {
    isEqual(a, b) {
        //如果a和b本來就全等
        if (a === b) {
            //判斷是否為0和-0
            return a !== 0 || 1 / a === 1 / b;
        }
        //判斷是否為null和undefined
        if (a == null || b == null) {
            return a === b;
        }
        //接下來判斷a和b的資料型別
        var classNameA = toString.call(a),
            classNameB = toString.call(b);
        //如果資料型別不相等,則返回false
        if (classNameA !== classNameB) {
            return false;
        }
        //如果資料型別相等,再根據不同資料型別分別判斷
        switch (classNameA) {
            case '[object RegExp]':
            case '[object String]':
                //進行字串轉換比較
                return '' + a === '' + b;
            case '[object Number]':
                //進行數字轉換比較,判斷是否為NaN
                if (+a !== +a) {
                    return +b !== +b;
                }
                //判斷是否為0或-0
                return +a === 0 ? 1 / +a === 1 / b : +a === +b;
            case '[object Date]':
            case '[object Boolean]':
                return +a === +b;
        }
        //如果是物件型別
        if (classNameA == '[object Object]') {
            //獲取a和b的屬性長度
            var propsA = Object.getOwnPropertyNames(a),
                propsB = Object.getOwnPropertyNames(b);
            if (propsA.length != propsB.length) {
                return false;
            }
            for (var i = 0; i < propsA.length; i++) {
                var propName = propsA[i];
                //如果對應屬性對應值不相等,則返回false
                if (a[propName] !== b[propName]) {
                    return false;
                }
            }
            return true;
        }
        //如果是陣列型別
        if (classNameA == '[object Array]') {
            if (a.toString() == b.toString()) {
                return true;
            }
            return false;
        }
    },
    // 物件深拷貝
    objDeepCopy (data) {
        return JSON.parse(JSON.stringify(data));
    }
}

export default mm;

 測試

呼叫 setState({},()=>( console.log("setState後的回撥方法...") ) 輸出結果

呼叫 setState({name:'avenda'},()=>( console.log("setState後的回撥方法...") ) 輸出結果