React中父組件與子組件之間的數據傳遞和標准化的思考


  React中父組件與子組件之間的數據傳遞的的實現大家都可以輕易做到,但對比很多人的實現方法,總是會有或多或少的差異。在一個團隊中,這種實現的差異體現了每個人各自的理解的不同,但是反過來思考,一個團隊用了同樣的UI,同樣的框架,實現方式確實有差異,這其實就是工程化的問題。

  回到React中父組件與子組件之間的數據傳遞的問題上來。

  父組件與子組件之間的數據傳遞的實現方式大致可以分為2種情況:

    1、子組件用自己的flux環傳遞數據,最后調用父組件的onChange事件將數據傳給父組件。

    2、子組件調用父組件的onChange事件,在父組件中的onChange事件中調用flux環傳遞數據到付組件的View層

  這2種方式各有優點,對比這兩種方式,在實時性上,第二種方式是通過調用父組件的onChange事件,數據改變是通過父組件的flux環發生改變的,所以是實時的,而第一種方式的數據是通過子組件自己的flux環改變的,最終傳給父組件,所以非實時;而在粒度上,這2種方式是相同的,都是維護了一個局部邏輯。我們一般用子組件來實現一些頁面局部的復雜邏輯,如果這個邏輯內部的數據處理也很復雜(要根據各種情況作出不同的判定、改變),那么第一種無疑更為合適,而更為現實的情況是,往往局部的復雜邏輯的實現在子組件內部還有子組件的子組件,這種情況下,優先選擇第一種方式;那么相對的如果這個數據處理比較簡單,我們完全可以將整個子組件看做頁面上的一個輸入框(也可以是其他實現某個功能的對話框),那么父組件中的一個輸入框調用父付組件的onChange事件來改變數據流,毫無疑問,第二種方式更為合理些。

  按照第二種方式,我們經常可以在父組件中看到如下的局部代碼:

    onChange: function(property, value) {
        Action.changePromotionDetail(property, value);
    },

    render: function() {
        return (
            <div className="xui-promotion-flashSalePage">
                <ProductInfo onChange={this.onChange} />
                <PromotionInfo onSubmit={this.onSubmit}
                               onChange={this.onChange}
                               promotionName={this.state.promotionName}
                               advert={this.state.advert}
                               promotionRangeDate={this.state.promotionRangeDate}
                               memberGrades={this.state.memberGrades}
                               memberGrade={this.state.memberGrade}
                               promotionPrice={this.state.promotionPrice}
                               numPerPurchase={this.state.numPerPurchase}
                               period={this.state.period}
                               numPerPeriod={this.state.numPerPeriod} />
            </div>
        )
    }

  如果傳入子組件的屬性和方法越多,那么代碼的可讀性其實越差,維護起來也更不方便,甚至在父組件的Store中還需要對數據流做許多處理,類似:

    changePromotionDetail: function(action) {
        if (...) {
            this.data[action.data.property] = ...;
        } else {
            this.data[action.data.property] = action.data.value;
        }
        
        this.__emitChange();
    }

  那么我們又需要思考,如果我們像上面所說的將子組件看做一個輸入框,一個輸入框應該只需要輸入一個值,父組件不應該接受那么多的不同屬性的數據,同時父組件需要做的只是將接受到的一個數據通過flux環傳遞給父組件的View層。那么我們可以采用的一種方法是子組件的數據變更先調用子組件的onChange事件,並在其中做好必要的數據處理,然后將數據添加到一個對象中,以一個數據處理完畢的對象的形式調用父組件的onChange事件:

    onChange: function(property, value) {
        if (property == '...') {
            // do someting here...
        } else {
            // do someting here...
        }

        var obj = {
            // some key/value here
        };

        this.props.onChange(obj);
    }

  這樣父組件中的代碼就可以簡化為如下:

    onChange: function(obj) {
        Action.changePromotionDetail(obj);
    },

    render: function() {
        return (
            <div className="xui-promotion-flashSalePage">
                <ProductInfo onChange={this.onChange} />
                <PromotionInfo onSubmit={this.onSubmit}
                               onChange={this.onChange}
                               infoObj={this.state.infoObj} />
            </div>
        )
    }

  再回到標准化的思考上,以React為例,React本身只是一個UI,facebook推薦了flux的架構,這就是一種實現方式,那么一個團隊在大方向上采用的技術和實現方式其實就確定了下來。如果我們進一步的細分,對諸如父組件和子組件之間的數據傳遞的方式,數據傳遞的格式等等作出限制,看上去好像限制了研發編程的自由,同時將研發的工作變成了機械的重復,但是換個角度,這樣的限制必然提高了研發效率,每個人碰到不同的場景都有了統一的應對策略;這樣的限制也必然降低維護的成本,每個人都能理解他人的編程思路。這就是工程化的一部分。

  編程就是為了解決問題,要想解決問題又需要考慮2個問題:

    1、工具。

    2、方式。

  工具是學不完的,尤其現在前端的工具井噴式的發展(雖然側面說明了前端工具的匱乏~),到這個公司用React,以后跳槽去了另一家又用Angular,后來換了部門,這個部門又用Vue。

  那么,作為研發,或許可以思考第二個問題,標准化的方式。每個公司每個部門都會有一套標准,你需要做的是先學會這套標准,同時去思考可以完善的地方,譬如這種場景沒有標准化的解決方案,你可以提出一個方案,如果被大家接受了,你的方案就成為了標准的一部分。

  這或許也是一條前端之路,一條提高編程效率與維護性的路,一條解決工程化部分問題的路。

   

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM