2015-12-08 20 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