标签:
摘要:做一个可以利用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,这样你的组件就会变得很小很简单。
标签:
原文地址:http://www.cnblogs.com/busicu/p/5377789.html