Reactjs的Controller View模式


摘要:做一個可以利用props來控制和傳遞所有狀態給其子組件的頂級組件是一件非常酷的事情

不要和“MVC”混淆了,只有能夠控制和傳遞所有的“state”的頂層組件,我們才叫它"view controller"或者"controller view"。

對於任何的頂層組件,例如<HomePage />,我們創造一個<HomePageController/>,這個組件是在render方法里面利用props方法來傳遞所有我們需要的信息的。

例子

// Controller views are very simple
class HomePageController extends React.Component {
    // Normal Flux store listening
    componentDidMount() {
        Store1.on('change', this.onStoreChange);
        Store2.on('change', this.onStoreChange);
    }
    onStoreChange() {
        this.setState({
            data1: Store1.getData(),
            data2: Store2.getData()
        });
    }
    render() {
        // <HomePage /> has no internal state!
        return <HomePage
            data1={this.state.data1}
            data2={this.state.data2} />;
    }
}

Controller Views模式的好處

組件更加的便捷

假設你有一個叫<ShoppingCartView/>的組件和一個叫<ShoppingCartStore/>的組件,我們需要一個組件來直接監聽store組件的狀態,這個很明顯的。但是后來再次假設你有兩份<ShoppingCartView/>要同時從不同的stroe里面直接讀取數據,這時候要怎么辦,假設你有一個叫<ShoppingCartController />的組件的話,你就可以監聽多個store然后利用props來渲染每一個子組件。

如下例子

class ShoppingCartController extends React.Component {  
    ...
    // You get component portability for free!
    render() {
        return <div>
            <ShoppingCart data={store1Data} />
            <ShoppingCart data={store2Data} />
        </div>;
    }

 

react router配合的天衣無縫

React Router有一個指向每一個頁面的<RouteHandler />,如果你有一個view controller的話,你就已經有一個 route handler了

<Route name="home" path="/" handler={ HomePageController } /> 

 

如果你的組件需要讀取URL里面的參數的話,這個就顯得更為重要了。

例如context.router.getCurrentQuery(),你利用props來傳遞URL的參數渲染,而不是把你的渲染方法里面弄的連七八糟。現在你的子組件在props的幫助下得到最簡介的渲染,而不是子組件來獲取URL的參數然后在此渲染。

你也可以把willTransition當做controller view的一個鈎子,這個鈎子用來讓你的子組件更加的便捷,因為他們從來不用擔心直接處理路由請求的問題。

 

減少開銷

 

狀態控制在計算機系統里面是不被推薦的,因為一個方法很難在看一眼之后就被理解,你需要撥開細節去查看內容。

假如你嵌套組件,並且每一個組件都自己處理他們的狀態,那你的應用將會很難被人理解。

但一個組件只需要純粹只根據props獲取的數據來渲染時,我們就會對這個組件的輸出更容易理解。因為組建有這明確的輸入。

更容易測試

如果想測試一個子組件,只想測試這個組件的特定的props和明確的渲染輸入結果,你將不用編造測試場景和請求動作。

 

問答

如果嵌套多個“View Controllers”會怎么樣?

Controller views並不是總是頂層組件,例如<HomePageController />可以渲染他的子組件<SignupLightbox />,從代碼結構上說的話,lightbox 被嵌套在Controller views里面,<HomePageController />必須來檢測所有的狀態來渲染lightbox嗎?

答案是否定的。如果lightbox組件在多個頁面都有展示的話,這樣由<HomePageController />來控制lightbox是一個不錯的辦法,但是lightbox從概念來來說的話,它也是一個頂層組件,盡管從代碼結構上看它被嵌套在了其他的組件里面。

一個子組件可以呀有任何的內部狀態嗎?

可以有的。實際上,在controller view中,使用內部狀態會更加明顯。例如你有一個組件叫<SearchForm />,那么它可以有一個存儲你子組件需要的數據叫this.state.unsubmittedSearch,

關注

這個controller view主要是解決的問題是組件的嵌套問題。controller view需要很小很簡單,如果你有很深層次的組件嵌套的話,你的controller view也會變得很大很笨拙,因為你需要傳遞好多的props和更改好多的狀態。

像這種特定的情景的解決方案,但是這種通常是代碼直覺,你需要評估你的組件樹,從而來自己判斷被嵌套的組件是有意義的。

例如你有一個20多頁的多步驟表單,那你就需要船度很多的props,但是如果每一步都有一個針對特定的url的controller view,這樣你的組件就會變得很小很簡單。


免責聲明!

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



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