react component 模式
有状态组件(Stateful)和无状态组件(Stateless)、容器组件(Container)与展示组件(Presentational)、高阶组件(HOC)、渲染回调(Render Callbacks)等
我在工作中使用 React 有一段时间了——一个 facebook 使用 js 渲染用户界面的框架——刚开始的时候我想知道一些概念。这些文字是尝试总结我实践这么久以来学到的一些模式——可能对于刚开始进入组件世界的开发者有用。
有状态(Stateful) 与 无状态(Stateless) 组件
就像有状态和无状态的 web 服务一样, React 组件也能在用户使用时保存和操作状态(有状态)。或只是一个简单的组件,按受 props 并返回需要显示的内容(无状态)。
一个简单的 无状态 按钮组件只接受 props:
而下面是一个 有状态 的计数组件(使用了 Button
组件):
就像你所看到的,最后一个组件的 constructor 保持了一个组件的 state, 而第一个组件则是一个简单组件,只通过 props 渲染了文字。这个关注分离可能非常简单,但是让 Button
组件高度复用。
容器(Container) 与 展示(Presentational) 组件
当使用外部数据运行时,我们可以把这个组件分成这两个新类别。容器组件 负责获取数据,存在在 react 作用域外部,就像连接 Redux 或 Relay ———— 而 展示组件 则不依赖 react 应用的其他部分,仅仅取决于它自身的 state 和接收的 props。让我们拿用户列表作为展示组件的例子:
这个列表可以使用我们的 容器组件 更新:
这种方法将数据获取与渲染分离,同时让 UserList
高度复用。如果你想进一步学习这种模式,这里有一篇文章解释地很好。
高阶组件
高阶组件————或叫 HOC。当你想要重用逻辑的时候非常感兴趣。他们是 javascript 函数,将一个组件作为参数,并返回新组件。
假设你需要做一个可伸缩的的菜单组件,当用户点的时候,展示它里面的内容。所以,为了替代在父级组件上控制 state,你可以简单地创建一个通用的 高阶组件 来处理它:
这种方式允许我们将逻辑应用通过装饰模式(decorator)应用在 ToggleableMenu
组件上。
现在我们可以任意传递子级到 ToggleableMenu
组件了:
如果你熟悉使用 redux
的 connect
或 react router 的 withRouter
函数,那你已经在用 HOCs 了。
渲染回调(Render Callbacks)
另一种让组件逻辑复用的很棒的方法是 将组件子级转换成函数。这也是为什么 渲染回调(Render Callbacks) 也叫作 Function as Child Components。我们可以拿可伸展的菜单高阶组件作为例子,并使用 渲染回调 重写它。
现在我们可以传递一个函数作为 Toggleable
的子组件:
上面的代码已经使用函数作为子级,但,如果我们想要像高阶组件的例子那样复用它(多个菜单),我们可以简单地使用 Toggleable
逻辑创建一个新组件:
我们的新产品 ToggleableMenu
组件已经准备好了:
这种方式真的非常有用,当我们需要更改渲染内容而不用管 state 操作时:就像你所看到的,我们可以将渲染逻辑移动到 ToggleableMenu
的子级函数中,但却保持我们 Toggleable
组件的 state 逻辑!
进一步阅读
上面的例子只是一些可以用在 react 编程中的基础模式,如果你真的想深入这个主题,我建议你看看这些了不起的文章: