title: react文档2-其它概念
date: 2018.9.21
tags:


高级指南: http://react.css88.com/docs/optimizing-performance.html

2018.9.21 星期五 10:21

1 Accessibility

。。。

3 上下文(Context)

上下文(Context) 提供了在组件之间共享这些值的方法,而不必在树的每个层级显式传递一个 prop 。

const ThemeContext = React.createContext('light');

class App extends React.Component {
  render() {
    return (
      <ThemeContext.Provider value="dark">
        <Toolbar />
      </ThemeContext.Provider>
    );
  }
}
function ThemedButton(props) {
  return (
    <ThemeContext.Consumer>
      {theme => <Button {...props} theme={theme} />}
    </ThemeContext.Consumer>
  );
}

// ----------
<Provider value={/* some value */}> 
<Consumer>
  {value => /* render something based on the context value */}
</Consumer>

## 何时使用 Context
## API
### React.createContext
const {Provider, Consumer} = React.createContext(defaultValue);
创建一个 { Provider, Consumer } 对。当 React 渲染 context Consumer 时,它将从组件树中匹配最接近的 Provider 中读取当前的 context 值。
### Provider
### Consumer
需要接收一个 函数作为子节点。 该函数接收当前 context 值并返回一个 React 节点。
## 示例
### 动态 Context
### 从嵌套组件更新 context
### 使用多个 context
### 在生命周期方法中访问 Context
是将 context 添加到每个生命周期方法中, 你只需将它作为 props , 然后像使用 props 一样使用它即可。
### 高阶组件中的 Context
### 转发 Refs 给 context Consumer(使用者)
## 告诫

18. 严格模式(Strict Mode)

注意: 严格模式检查只在开发模式下运行,不会与生产模式冲突。
你可以在应用的任何地方启用严格模式

function ExampleApplication() {
  return (
    <div>
      <Header />
      <React.StrictMode>
        <div>
          <ComponentOne />
          <ComponentTwo />
        </div>
      </React.StrictMode>
      <Footer />
    </div>
  );
}

StrictMode目前有助于:

16. 渲染属性(Render Props)

术语 “render prop” 是指一种简单的技术,用于使用一个值为函数的 prop 在 React 组件之间的代码共享。

带有渲染属性(Render Props)的组件需要一个返回 React 元素并调用它的函数,而不是实现自己的渲染逻辑。
## 在交叉关注点(Cross-Cutting Concerns)使用 render props
组件在 React 是主要的代码复用单元,但如何共享状态或一个组件的行为封装到其他需要相同状态的组件中并不是很明了。
例如,下面的组件在 web 应用追踪鼠标位置:
这也是 render prop 的来历:我们可以提供一个带有函数 prop 的 组件,它能够动态决定什么需要渲染的,而不是将 硬编码到 组件里,并有效地改变它的渲染结果。
更具体地说,render prop 是一个组件用来了解要渲染什么内容的函数 prop。
这一技术使得共享代码间变得相当便利。为了实现这一行为,渲染一个带有 render prop 的 组件能够告诉它当前鼠标坐标 (x, y) 要渲染什么。

关于 render props 一个有趣的事情是你可以使用一个带有 render props 的常规组件来实现大量的 高阶组件 (HOC)。

## 使用 Props 而非 render
记住仅仅是因为这一模式被称为 “render props” 而你 不必为使用该模式而用一个名为 render 的 prop。实际上,组件能够知道什么需要渲染的任何函数 prop 在技术上都是 “render prop” 。

## 警告
### 在 React.PureComponent 中使用 render props 要注意
如果你在 render 方法里创建函数,那么使用 render prop 会抵消使用 React.PureComponent 带来的优势。这是因为浅 prop 比较对于新 props 总会返回 false,并且在这种情况下每一个 render 对于 render prop 将会生成一个新的值。

为了绕过这一问题,有时你可以定义一个 prop 作为实例方法,类似如下:

15. Refs 和 DOM

Refs 提供了一种访问在 render 方法中创建的 DOM 节点或 React 元素的方式。

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.myRef = React.createRef();
  }
  render() {
    return <div ref={this.myRef} />;
  }
}

## 何时使用 Refs
如果可以通过声明式实现,就尽量避免使用 refs 。
## 不要过度使用 Refs
在组件层中,通常较高级别的 state 更为清晰。有关示例,请参考状态提升。

下面的例子已经用 React v16.3 引入的 React.createRef() API 更新。
## 创建 Refs
使用 React.createRef() 创建 refs,通过 ref 属性来获得 React 元素。当构造组件时,refs 通常被赋值给实例的一个属性,这样你可以在组件中任意一处使用它们.
## 访问 Refs
当一个 ref 属性被传递给一个 render 函数中的元素时,可以使用 ref 中的 current 属性对节点的引用进行访问。
## 为 类(Class) 组件添加 Ref
## Refs 与 函数式组件
你不能在函数式组件上使用 ref 属性,因为它们没有实例:
如果你需要使用 ref ,你需要将组件转化成 类(class)组件,就像需要 生命周期方法 或者 state 一样。

然而你可以 在函数式组件内部使用 ref 来引用一个 DOM 元素或者 类(class)组件:
## 对父组件暴露 DOM 节点
如果你使用 React 16.3 或更高, 这种情况下我们推荐使用 ref 转发。
可能的话,我们不建议暴露 DOM 节点,
## 回调 Refs
React 也支持另一种设置 ref 的方式,称为“回调 ref”,更加细致地控制何时 ref 被设置和解除。

React 将在组件挂载时将 DOM 元素传入ref 回调函数并调用,当卸载时传入 null 并调用它。ref 回调函数会在 componentDidMout 和 componentDidUpdate 生命周期函数前被调用

你可以在组件间传递回调形式的 refs,就像你可以传递通过 React.createRef() 创建的对象 refs 一样。

## 旧版API: String 类型的 Refs
我们不建议使用,因为string类型的 refs 存在问题。已经过时了,可能会在未来的版本是移除。

5 转发 Refs

Ref 转发是一种自动将 ref 通过组件传递给子组件的技术。
## 转发 refs 给 DOM 组件
Ref 转发是一种选择性加入的功能,可让某些组件接收他们收到的 ref,并将其向下传递(换句话说,“转发”)给孩子。

在下面的例子中, FancyButton 使用 React.forwardRef 来获取传递给它的 ref , 然后将其转发给它渲染的的 DOM button:

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">

{props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

## 组件库维护者的注意事项
## 在高阶组件中转发 refs
## 在DevTools中显示一个自定义名称

6 片段(Fragments)

React 中一个常见模式是为一个组件返回多个元素。 片段(fragments) 可以让你将子元素列表添加到一个分组中,并且不会在DOM 中增加额外节点。

class Columns extends React.Component {
  render() {
    return (
      <React.Fragment> // 简写 <> 
        <td>Hello</td>
        <td>World</td>
      </React.Fragment>// 简写 </> 
    );
  }
}

## 简写语法
您可以像使用其他元素一样使用<></>,只是它不支持 键(keys) 或 属性(attributes)。
请注意, 目前许多工具都不支持这个简写语法 , 所以你可能需要明确地使用
## 带 key 的 片段(fragments)
如果你需要一个带 key 的片段,你可以直接使用 <React.Fragment /> 。 一个使用场景是映射一个集合为一个片段数组 — 例如:创建一个描述列表:

key 是唯一可以传递给 Fragment 的属性。在将来,我们可能增加额外的属性支持,比如事件处理。

11. 插槽(Portals)

Portals 提供了一种很好的方法,将子节点渲染到父组件 DOM 层次结构之外的 DOM 节点。
ReactDOM.createPortal(child, container)
## 用法
通常来说,当你从组件的 render 方法返回一个元素时,它将被作为子元素被装载到最近父节点 DOM 中:
然而,有时候将子元素插入到 DOM 节点的其他位置会有用的:

render() {
  // React *不* 会创建一个新的 div。 它把 children 渲染到 `domNode` 中。
  // `domNode` 可以是任何有效的 DOM 节点,不管它在 DOM 中的位置。
  return ReactDOM.createPortal(
    this.props.children,
    domNode,
  );
}

## 通过 Portals 进行事件冒泡

4 错误边界(Error Boundaries)

部分 UI 中的 JavaScript 错误不应该破坏整个应用程序。 为了解决 React 用户的这个问题,React 16引入了一个 “错误边界(Error Boundaries)” 的新概念。

错误边界是 React 组件,它可以 在子组件树的任何位置捕获 JavaScript 错误,记录这些错误,并显示一个备用 UI ,而不是使整个组件树崩溃。 错误边界(Error Boundaries) 在渲染,生命周期方法以及整个组件树下的构造函数中捕获错误。

错误边界 无法 捕获如下错误:

render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return

Something went wrong.

;
}
return this.props.children;
}
}
// 而后你可以像一个普通的组件一样使用:




`

20. 不受控组件

在大多数情况下,我们推荐使用受控组件来实现表单。…
另外一个选择是不受控组件,其表单数据由 DOM 元素本身处理。

要编写一个未控制组件,你可以使用一个 ref 来从 DOM 获得 表单值,而不是为每个状态更新编写一个事件处理程序。

因为不受控组件的数据来源是 DOM 元素,当使用不受控组件时很容易实现 React 代码与非 React 代码的集成。如果你希望的是快速开发、不要求代码质量,不受控组件可以一定程度上减少代码量。否则。你应该使用受控组件。

## 默认值
在不受控组件中,你可能希望 React 有初始值,但保留后续更新不受控制。
defaultValue,defaultChecked
## file input 标签
始终是一个不受控制的组件,因为它的值只能由用户设置,而不是以编程方式设置。

7 高阶组件(Higher-Order Components)

高阶组件(HOC)是 React 中用于重用组件逻辑的高级技术。 HOC 本身不是 React API 的一部分。 它们是从 React 构思本质中浮现出来的一种模式。
具体来说,高阶组件是一个函数,能够接受一个组件并返回一个新的组件。(组件是将 props 转化成 UI)
## 在横切关注点中使用高阶组件
## 不要改变原始组件,而是使用组合
高阶组件使用容器作为其实现的一部分。你可以将高阶组件视为定义参数化容器组件。
## 约定: 给包裹组件传递不相关的属性(Props)
## 约定: 最大化组合(Maximizing Composability)
## 约定:为了方便调试包装显示名称(display name)
## 警告
### 不要在render函数中使用高阶组件
### 静态方法必须复制
### Refs不会被传递

21. Web 组件(Web Components)

React 和 web组件 被用以解决不同问题。
Web组件为可重用组件提供了强大的封装能力,
而React则是提供了保持DOM和数据同步的声明式库。
二者目标互补。作为开发者,你可以随意地在Web组件里使用React,或者在React里使用Web组件,或都有。

大部分使用 React 的开发者并不使用Web组件,但你可能想要,尤其若你正在使用那些用 Web组件编写的第三方UI组件。

12:21