高阶组件

Higher-Order Components, 高阶组件

高阶组件就是一个函数,传给它一个组件,它返回一个新的组件。新的组件使用传入的组件作为子组件。

高阶组件就是为了组件之间的代码复用,组件可能有着某些相同的逻辑,把这些逻辑抽离出来,放到高阶组件中进行复用;
高阶组件内部的包装组件和被包装组件之间通过 props 传递数据。

高阶组件有助于提高我们代码的灵活性、逻辑的复用性。

React.js 的 context

React.js 的 context 其实就像组件树上某颗子树的全局变量,某个组件只要往自己的 context 里面放了某些状态,这个组件之下的所有子组件都直接访问这个状态而不需要通过中间组件的传递。

一个组件的 context 只有它的子组件能够访问,它的父组件是不能访问到的。

一个组件可以通过 getChildContext 方法返回一个对象,该对象就是子树的 context,而且提供 context 的组件必须提供 childContextTypes 作为 context 的声明和验证。
任意深度的子组件可以通过 contextTypes 来声明想要的 context 里面的状态,然后通过 this.context 访问到那些状态。

context 打破了组件和组件之间通过 props 传递数据的规范,极大地增强了组件之间的耦合性,但也因为能被随意接触就能被随意修改。

一些第三方的前端应用状态管理的库(例如 Redux)就是充分地利用了这种机制给我们提供便利的状态管理服务。所以以后都不要直接接触 context,只需要用好第三方的应用状态管理库就好。

纯函数(Pure Function)

纯函数:一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用。也即:

  1. 函数的返回结果只依赖于它的参数;
  2. 函数执行过程里面没有副作用;

如果应用程序中,大多函数都是由纯函数组成,那么程序的测试和调试都会变得非常方便。

Redux 与 React-redux

Redux 和 React-redux 并不是同一个东西,Redux 是一种架构模式(Flux 架构的一种变种),他不关注你用什么库,可以把它应用到 React 或者 Vue,甚至是 jQuery。

而 React-redux 就是把 Redux 这种架构模式和 React.js 结合起来的一个库,就是 Redux 架构在 React.js 中的体现。

学习 React.js 团队的做法:把事情搞复杂一些,提高数据修改的门槛:模块(组件)之间可以共享数据,也可以改数据;但是我们约定,这个数据并不能直接改,你只能执行某些我允许的某些修改,而且你修改的必须大张旗鼓地告诉我。

React.js 除了状态提升以外并没有更好的办法帮我们解决组件之间共享状态的问题,而使用 context 全局变量让程序不可预测。而 store 里面的内容是不可以随意修改的,而是通过 dispatch 才能变更里面的 state。所以尝试把 store 和 context 结合起来使用,可以兼顾组件之间共享状态问题和共享状态可能被任意修改的问题。

写 reducer 文件的习惯:

  1. 定义 action types
  2. 编写 reducer
  3. 跟这个 reducer 相关的 action creators

Smart 组件 vs Dumb 组件

根据是否需要高度的复用性,把组件划分为 Dumb 和 Smart 组件,约定俗成所有的 Dumb 组件都放在 components/ 目录下,所有的 Smart 的组件都放在 containers/ 目录下。

Dumb 组件基本只做一件事情 —— 根据 props 进行渲染,而 Smart 组件则是负责应用的逻辑、数据,把所有相关的 Dumb(Smart)组件组合起来,通过 props 控制它们。

注意一点,Smart 组件并不意味这完全不能复用,Smart 组件的复用性是依赖场景的,在特定的应用场景下当然是可以复用 Smart 组件的;而 Dumb 组件则是可以跨应用场景复用。也即 Smart 和 Dumb 组件都可以复用,只是程度、场景不一样。