原文地址:https://medium.com/teamsubchannel/react-component-patterns-e7fb75be7bb0
作者:William Whatley
摘要:本文介绍了4种组件类型:容器组件、展示组件、高阶组件和渲染回调。

今天,我想花一点时间来分享我学习React组件模式的经验。这个想法来源于一次聚会时的技术交流。组件是React的核心,因此有必要去理解如何使用它们。

以下的例子都脱胎于Michael Chan gave on React component patterns这个视频的思想。我非常推荐你们看一看。

什么是组件?

reactjs.org上说:“组件能够将你的界面分割成独立且可复用的小块,而这些小组件都是互相独立的。”

当你第一次执行npm install react命令的时候,你得到了一个组件以及相关的API。与JS的函数类似,一个组件接收输入,叫做props。然后返回React元素,作用是描述UI界面的样式。这就是React作为声明式API的表现形式,因为你只需要告诉它你想要展示的UI,剩下的React都会帮你完成。

对于声明式API的概念,你可以想象成滴滴打车的场景——告诉司机你的目的地,接着让他来完成开车的工作。而命令式API不同,你将完成所有任务,既是乘客,也是司机。

组件API

当你在安装好React后,得到了5类API:

  • render
  • state
  • props
  • context
  • lifecycle events

尽管写组件时可以把上面所有的API都使用一遍,但是你很快会发现一些组件只需要用到某些API,而另一些组件也只会使用另一些特定的API。而这两类组件往往被划分为有状态与无状态组件两大类。有状态的组件会有代表性地使用有状态API:render、state和生命周期。但无状态组件只会使用render、props和context。

以上就是我们在介绍组件模式前所需要的知识铺垫。组件模式是设计组件的最佳实践,最初是把组件切割成数据/逻辑层和UI/展示层。通过拆分组件的职责,能够设计出更容易复用、更内聚的组件,从而组装成复杂的UI界面。这个特性对于构建可扩展的应用时是非常重要的。

组件模式

常用的组件模式有:

  • 容器组件
  • 展示组件
  • 高阶组件HOC
  • 渲染回调

容器组件

“容器组件的作用是获取数据和渲染子组件。”——Jason Bonta

蓝色代表容器组件,灰色代表展示用的子组件

容器组件使用了有状态的API,封装了数据逻辑层。通过使用生命周期,你可以连接Redux或Flux等状态管理库,然后把数据和回调函数当作props传递给子组件。在容器组件的render方法中,你可以用子展示组件来拼装UI界面。容器组件往往都设计成一个类组件,而不是纯函数组件,为的就是能够使用所有有状态的API。

在下面的例子中,我们有一个名为Greeting的有状态的类组件,包括componentDidMount()render方法。

class Greeting extends React.Component {constructor() {super();this.state = {name: "",};}componentDidMount() {// AJAXthis.setState(() => {return {name: "William",};});}render() {return (<div><h1>Hello! {this.state.name}</h1></div>);}
}

这时,这个组件仅仅是一个有状态的类组件。为了让它成为一个真正的容器组件,我们要把UI部分放进一个展示组件中。下面就来讲讲展示组件。

展示组件

展示组件使用到props、render和context这些无状态API,并且可以写成更简洁优雅的函数式无状态组件。

const GreetingCard = (props) => {return (<div><h1>Hello! {props.name}</h1></div>)
}

展示组件只能从父级组件或容器组件传来的props中接收数据和回调函数。

蓝色代表展示组件,而灰色代表容器组件。

容器组件和展示组件合并起来后,封装成了一个真正被使用的组件:


const GreetingCard = (props) => {return (<div><h1>{props.name}</h1></div>)
}class Greeting extends React.Component {constructor() {super();this.state = {name: "",};}componentDidMount() {// AJAXthis.setState(() => {return {name: "William",};});}render() {return (<div><GreetingCard name={this.state.name} /></div>);}
}

如你所见,我把Greeting类组件中的UI部分移除,放入一个无状态的函数组件中。当然,这只是一个简单的例子,但对于复杂的应用来说,这是最基本的做法。

高阶组件(HOC)

高阶组件就是一个把组件当作参数,并且返回新组件的函数。

它的强大之处在于能够给任意数量的组件提供数据源,并且可以被用来实现逻辑复用。用react-router-v4或Redux举个例子。使用react-router-v4时,你可以使用withRouter()来继承传给组件的props。而使用Redux时,你通过使用connect({})()来把actions当作props传递给子组件。

虚线表示的是高阶组件,它能够返回一个新的组件。

看看这个例子:

import {withRouter} from 'react-router-dom';class App extends React.Component {constructor() {super();this.state = {path: ''}}componentDidMount() {let pathName = this.props.location.pathname;this.setState(() => {return {path: pathName,}})}render() {return (<div><h1>Hi! I'm being rendered at: {this.state.path}</h1></div>)}
}export default withRouter(App);

当导出我的组件时,我使用react-router-v4提供的withRouter()方法把它包裹起来。而在App的componentDidMount()生命周期中,我通过this.props.location.pathname来更新状态。在被withRouter()包裹后,我的类组件现在可以通过props访问react-router-v4的方法,就像this.props.location.pathname。像这样的例子,实在是不胜枚举。

渲染回调(render callbacks)

与高阶组件类似,渲染回调或者说渲染props都是用来实现组件逻辑复用功能。相比较于大多数开发者使用的高阶组件,渲染回调也有自己的优势。具体优势可以阅读Michael Jackson所写的这个视频——《Never write another HOC.》。视频中所讲的关键点就是渲染回调能够减少命名空间的冲突并且解释逻辑的来源。

蓝色虚线代表渲染回调函数。

class Counter extends React.Component {constructor(props) {super(props);this.state = {count: 0,};}increment = () => {this.setState(prevState => {return {count: prevState.count + 1,};});};render() {return (<div onClick={this.increment}>{this.props.children(this.state)}</div>);}
}class App extends React.Component {render() {return (<Counter>{state => (<div><h1>The count is: {state.count}</h1></div>)}</Counter>);}
}

在上面的Counter类中,我在render里使用了this.props.children,然后把this.state当作参数传给这个函数。之后在App类中,我把想要展示的组件用Counter组件包裹起来,这样就能使用Counter的代码逻辑了。render函数的返回结果是代码28行,在那里我通过{state => ()}自动获取到Counter的state。

感谢您的阅读

我很乐意接受大家的意见来使我成长。我对React组件模式的见解还不够成熟,所以我也算是在写作中学习吧。

查看更多我翻译的Medium文章请访问:
项目地址:https://github.com/WhiteYin/translation
SF专栏:https://segmentfault.com/blog/yin-translation

[翻译]React组件模式相关推荐

  1. React的组件模式

    组件是 React 的核心,因此了解如何利用它们对于创建优秀的设计结构至关重要. 什么是组件 根据 React 官网的介绍,"组件让你可以将 UI 分割成独立的.可重用的部分,并独立管理每个 ...

  2. React的组件模式 1

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: 组件是 React 的核心. 原文:React的组件模式 作者:前端小智 Fundebug经授权转载,版权归原作者所有 ...

  3. react测试组件_测试驱动的开发,功能和React组件

    react测试组件 This article is part of my studies on how to build sustainable and consistent software. In ...

  4. 编写react组件_React组件的“黄金法则”如何帮助您编写更好的代码

    编写react组件 以及钩子如何发挥作用 (And how hooks come into play) Recently I've adopted a new philosophy that chan ...

  5. 使用TypeScript映射和条件类型使React组件更出色

    by Deepu K Sasidharan 通过Deepu K Sasidharan 使用TypeScript映射和条件类型使React组件更出色 (Make your React component ...

  6. React组件设计实践总结05 - 状态管理

    今天是 520,这是本系列最后一篇文章,主要涵盖 React 状态管理的相关方案. 前几篇文章在掘金首发基本石沉大海, 没什么阅读量. 可能是文章篇幅太长了?掘金值太低了? 还是错别字太多了? 后面静 ...

  7. react中的状态机_在基于状态图的状态机上使用React的模式

    react中的状态机 by Shawn McKay 肖恩·麦凯(Shawn McKay) 在基于状态图的状态机上使用React的模式 (Patterns for using React with St ...

  8. react开发模式_通过开发带有精灵动画的游戏来学习高级React模式

    react开发模式 by Pavel Vlasov 通过帕维尔·弗拉索夫(Pavel Vlasov) 通过开发带有精灵动画的游戏来学习高级React模式 (Learn advanced React p ...

  9. 编写react组件_如何编写第一个React.js组件

    编写react组件 React的函数和类组件,道具,状态和事件处理程序 (React's function and class components, props, state, and event ...

最新文章

  1. 语言 重量计算_大师之光:有种跨越国界的语言叫C++
  2. bgi::detail::intersection_content用法的测试程序
  3. MySQL为其他用户创建数据库_MYSQL添加新用户 MYSQL为用户创建数据库 MYSQL为新用户分配权限...
  4. BZOJ3245: 最快路线 拆点dijkstra
  5. 操作系统(6)-协程
  6. Spring 简化配置(了解/不推荐)
  7. python 函数可以作为容器对象的元素_14、函数对象和闭包
  8. High ASCII字符从bat文件到dos控制台的转化问题
  9. 多数据源一致性事务解决方案
  10. world: 对比两个文档
  11. Qt + 运动控制 (固高运动控制卡)【3】运动控制卡几种常用的回零方式
  12. 侠众道武功最佳练级方案_千年练级经验总结
  13. 京东零售大数据云原生平台化实践
  14. iOS - 苹果审核被拒3.2(f)
  15. ccsa安学网小程序_CCSA安学网题库1
  16. 解决webpack : 无法加载文件 C:\Users\XXX\AppData\Roaming\npm\webpack.ps1因为在此系统上禁止运行脚本
  17. 业内人士真心话:只会测试没有前途的,我慌了....
  18. 输入一段字符,统计一段字符串中大小写字母的个数
  19. 国内十大互联网黄金交易平台排名
  20. TMS320F2812介绍

热门文章

  1. 出现ORA - 1017用户名/口令无效; 登录被拒绝 的问题
  2. ON TOP-N and pagination queries
  3. android studio 初次使用Kotlin(环境准备篇)
  4. android Map集合的遍历
  5. WebKit Event
  6. VirtualAlloc和VirtualCopy----VirtualFree
  7. Android 高级Drawable资源---复合Drawable----变换Drawable---RotateDrawable用法实例
  8. Android数据绑定框架DataBinding用法
  9. 2019牛客暑期多校训练营(第七场)J A+B problem
  10. Asp.Net 数据分页