现在为止我使用 React.js 已 经6 个月了。6 个月 放长远看一点也不长。但是,在 JavaScript 框架层出不穷的今天,6 个月可以称为老前辈了。最近指点了几个新人入门 React ,所以想总结一下写篇文章启发更多的人。下面总结的这些点,一些点是我希望在自己入门的时候就已经知道的,另外一些则是让我真正的理解 React。 本文假定你已经有了一下基本的概念。如果你不熟悉 component、props 或者 state 这些名词,你最好先去阅读下官方起步和手册。下面的代码示例我将使用 JSX 作演示,因为使用 JSX 语法写组件更为简洁,也更具表达力。 1. React.js 只是一个视图库我们从最基本的开始。React 不是一个 MVC 框架,好吧,它根本就不是一个框架。它只是一个渲染视图的库。如果你对 MVC 熟悉的话,你就会意识到 React.js 只对应了 2. 组件尽可能的小这 一点有些显而易见,但是有必要强调一下。每个良好的程序员都知道,较小的类、模块更容易理解、测试和维护,对于组件来说也是一样。我起初犯的错误是低估了 React 组件合适的大小。当然,合适的大小取决于很多不同的因素(包括个人与团队偏好),但是,一般来说,我建议,让组件明显小于你本认为的必需大小。举个栗子, 我的个人网站主页上的这个组件,用于展示我的最新博文: 个组件本身是一个 3. 写函数式组件首先,我们有两种定义 React 组件的方式,第一种是用 另一种是 ES6 class 写法: React 0.14 引入了一个新语法来定义组件,使用属性作为参数的函数: 这是我最喜欢的定义 React 组件的方式。除了语法上简洁,这种方法还能帮助你界定什么时候需要拆分组件了。我们来回顾下之前的例子,假设下面是没拆分之前的代码: 这个 class 还凑合。我们已经从 render 方法中抽取了几个方法,方法足够小,命名合理。我们来试着用函数式的语法重写一下: 代码基本一样,无非是将类里的方法暴露为函数。但是,对我来说,区别可大了。在基于类的例子中,我看到的是 我就不再啰嗦函数式组件有助于我们遵循上面第二点。 以后,React 也会做一些优化,会使函数式组件比基于类的组件更为高效。(更新:函数式组组件的性能影响比我想象的要复杂。但是,如果性能不是大的问题,我依然推荐尽可能的写函数式组件,你应该好阅读下这个和这个,选择一个合适自己的) 还有个重要的店,函数式组件有几个 ’限制‘ ,我个人认为是大优点。第一个是它不会有 另一个大的区别是函数式组件不会有状态依附,我下一个点就是讲… 4. 写无状态组件不得不说,到目前为止,我觉得写 React 应用,最让我头疼的事都是由包含很多状态的组件引起的。 状态让组件很难测试单 纯的输入输出函数是最容易测试的,这点可以作为抛弃状态定义组件的理由吗?当我们测试很多状态的组件时,为了测试预期行为,我们必须先将组件设置为“正确 的状态”。我们还必须考虑到所有的状态(因为组件可能在任意时刻改变这些状态)和属性(不受组件控制)组合,然后再去考虑那个组合需要测试,怎么测试。如 果组件只是一个输入属性的处理函数,测试简直是不能更简单了。(关于测试,后面会讲)。 状态让组件很难推理(定位预期)当你读一段代码中包含很多状态的组件,特别费劲,你需要在脑海中记录组件的状态。这些问题:”状态有没有初始化?”,“如果我在这儿改变状态将会发生什么?”,“有几个地方改变了这个状态”,“这个状态是否存在条件竞争?”,这几个问题非常普遍。跟踪组件变化太蛋疼了。 状态让组件很容易引入业务逻辑我 们不应该搜索组件然后才能确定行为。记住,React 只是一个视图库,所以,把渲染逻辑丢在组件里面没问题,但是业务逻辑也丢里面就有问题了。但是呢,如果你的应用状态都在组件里面,那在组件内部访问这些状 态就会很方便,这样就会诱使你把业务逻辑也丢在里面。回顾下刚说的那点,这么做单元测试怎么办 - 没有业务逻辑你没法测试渲染逻辑,反之亦然。 状态让组件很难与应用其它部分共享信息父层组件的状态很容易传给下层组件,反过来就费事了。 当然,有时一个组件独立维护部分状态也是有必要的。在这种情况下,尽管放心使用 为组件添加状态还是需要慎重。一旦你开始了,就很容易再加一个状态,不知不觉就不受你控制了。 5. 使用 Redux.js上面第一点就已经说过,React 只是一个视图库。那么问题来了,“状态和逻辑放哪儿?” 我很高兴你会这么问! 我在考虑写一篇单独的博客,关于 Redux 的特性和优点。目前我推荐你读下官方文档,在这儿我只简单描述下它的工作原理:
上面的这些概念并非 Redux 独创,但是 Redux 的实现比较清晰简单。从 Alt.js 切换到 Redux ,减少了很多代码量,这儿简单列出比较突出的优点:
这儿有几个库配合 Redux 非常爽,我也推荐你使用:
Redux 是不是真正的 Flux,每个人都有自己的见解。个人觉得它符合 Flux 框架的核心思想,不过这个争论只是个语义问题。 6. 一直使用 propTypespropTypes 很容易为组件添加类型安全保障。他们看起来像这样: 在开发阶段(生产不会),如果任何组件没有给到必需的属性,或者所给的属性与声明的不匹配,React 会打印这些错误信息通知你。这有几点好处:
上面的这些点,你可能似曾相识,静态类型支持者的论点。个人来讲,我通常喜欢动态类型带来的开发速度和舒适,但是我发现 propTypes 可以毫不费力的为我的组件添加一些安全感。坦白讲,没有理由不一直用它们。 7. 使用浅渲染测试 React 组件依然是有点棘手的话题。不是因为太难,而是因为还在发展,还没有出现一个最佳方案。目前来看,我的 go-to 方法是使用 浅渲染和属性断言。 浅渲染很好用,它允许你完整的渲染一个单一组件,而不涉及子元素的渲染。也就是说,结果对象只会告诉你子元素的类型和属性。这样子单一组件单一时间点可以提供很好的隔离。这儿有三种类型的组件单元测试,我自己也经常这么做: 渲染逻辑假定一个组件,因条件不同,可能会显示一张图片,或者一个加载图标: 我们可以这么测试: 非常简单!当然,浅渲染的API 略微比我展示的复杂。上面使用的浅渲染函数是我们自己的 辅助方法,这个辅助方法包装了真正的 API,使用起来更简单一些。 属性转换在 最后的例子中,我们深入测试组件的子元素,确保它们被正确渲染。我们不止断言组件是否存在,同时检查所给的属性是否正确。当组件确实在传递属性之前根据属 性做些转换时,这点特别有用。例如,下面这个组件接受一个字符串数组作为 CSS 类名,往下传递一个单引号空白分割的字符串: 对这样方法最多的批判是激增的 用户交互当然,组件不止展示,还有交互: 这是我最喜欢的测试方法: 这只是一个例子,希望你能受到启发。 集成测试上面我内容只覆盖到组件的独立的单元测试,但是你可能想确保你的应用各个部分协同工作,想在测试上走的更远。我对这部分了解的不够深入,但是列出一些基本点:
关于测试驱动开发一般情况下,写React 组件时我并不使用测试驱动开发。 在开发组件的时候,我发现我经常会去改动它的结构,我需要使用最简单的 HTML 和 CSS,在需要支持的浏览器上保持一致。因为我的组件单元测试方法大多会断言组件的结构,而测试驱动开发会使我在修改DOM时,忙于修复测试用例,这看起来有点浪费时间。 8. 使用 JSX, ES6, Babel, Webpack 和 NPM只有 JSX 是 React 特有的。对我来说,JSX 是 9. 使用 React 和 Redux 开发工具谈到工具,React 和 Redux 的开发工具太赞了。React dev tools 让你审查 React 元素的渲染树,在查看浏览器中结果时相当有用。Redux dev tools 更是让人眼前一亮,让你看到每个 已经发生的 action ,它们引起的状态变化,甚至给你回退的能力!你可以作为开发依赖,或者浏览器扩展的形式使用。 就这些! via:fedeoo |