2015-12-08 43 views
1

我是React的新手,想要理解處理以下情況的正確方法。從React組件訪問常用功能/數據

說,我有三個陣營的是基本上兄妹即不相互嵌套組件。

這三個組件需要知道用戶的屏幕分辨率和本決議可能會改變。例如,用戶可以將瀏覽器窗口設置爲較小的尺寸。實質上,視圖端口處於動態狀態。

我不想把視圖端口檢測邏輯在其中將產生重複的代碼的每個組件。如何創建一個負責視圖端口檢測的通用函數並將這些信息傳遞給每個組件?

在下面的代碼示例中,我有一個相互獨立工作的三個組成部分,但他們會都需要查看端口信息。什麼是正確的方式來處理這個問題?

<div id="navigationHere"></div> 
<div id="doSomethingHere"></div> 
<div id="handleSomethingElseHere"></div> 

<script src="nav.jsx" type="text/jsx"></script> 
<script src="doSomething.jsx" type="text/jsx"></script> 
<script src="handleSomethingElse.jsx" type="text/jsx"></script> 

順便說一句,我用這一個ASP.NET MVC應用程序中,並考慮使用ReactJs.Net來處理在服務器端的初始狀態和預渲染。因此,瞭解在ASP.NET MVC應用程序的上下文中處理此問題的正確方法對我來說非常重要。

+0

像這樣的常見函數應該在父項和計算結果中作爲道具傳遞下來計算。 –

+0

我不確定我是否遵循你的邏輯。用戶可以調整瀏覽器窗口的大小,以便傳遞靜態值不起作用。其他選項是使用包含每個單獨組件的包裝器/父組件以及計算視圖端口的函數,但在這種情況下,對於具有不同模型的每個頁面,我們必須創建一個包裝器組件,並在該父級/包裝器組件,我們仍然會重複計算出視口的函數。 – Sam

+0

爲什麼要傳遞一個靜態值?在你的父母你會附加一個監聽器到'onResize'事件和每個resize事件你會傳遞組件的新值或我完全錯過了這一點? –

回答

1

這是一個很好的用例,稱爲高階組件。

首先我們定義一個跟蹤屏幕分辨率的父組件。

var ViewportManager = React.createClass({ 
    getInitialState: function() { 
    return this.measureViewport(); 
    }, 
    componentWillMount: function() { 
    window.addEventListener('resize', this.onResize); 
    }, 
    componentWillUnmount: function() { 
    window.removeEventListener('resize', this.onResize); 
    }, 
    onResize: function() { 
    this.setState(this.measureViewport()); 
    }, 
    measureViewport: function() { 
    return { 
     width: window.innerWidth, 
     height: window.innerHeight 
    }; 
    } 
}); 

安裝此組件後,它將跟蹤屏幕的大小,每次瀏覽器窗口調整大小時都會更新。我們現在需要做的是將這些值傳遞給這個內部渲染的任何組件。

<ViewportManager> 
    <NavigationHere /> 
    <DoSomethingHere /> 
    <HandleSomethingElseHere /> 
</Viewport> 

我們將傳承viewportHeightviewportHidth到每一個內部組件。

var ViewportManager = React.createClass({ 
    // ... 
    render: function() { 
    var viewportWidth = this.state.width; 
    var viewportHeight = this.state.height; 
    var children = this.props.children; 
    var additionalProps = { 
     viewportWidth: viewportWidth, 
     viewportHeight: viewportHeight 
    }; 

    var modifiedChildren = React.Children.map(children, function(child) { 
     return React.cloneElement(child, additionalProps); 
    }); 

    return (
     <div className='viewport-manager'> 
     {{ modifiedChildren }} 
     </div> 
    ); 
    } 
}); 

現在,所有直接在ViewportManager內部的組件都將獲得兩個額外的道具。

var NavigationHere = React.createClass({ 
    render: function() { 
    // I can see this.props.viewportWidth 
    // and this.props.viewportHeight 
    } 
}); 
+0

謝謝丹。也謝謝@limelights。我希望你能得到你的幫助。你非常有幫助。不知道我怎麼能給你在StackOverflow的信貸的所有幫助。 – Sam