React Doc
React 的官方文档 是个好东西,特别是 React 哲学, FAQ, Hooks FAQ
以下内容主要对应 文档-核心概念 章节
Props 的只读性
From
所有 React 组件都必须像纯函数一样保护它们的 props 不被更改
1 | // 不允许 |
正确使用 State(*3)
1. 不要直接修改 State
1 | // Wrong 不会重新渲染 |
2. State 的更新可能是异步的
出于性能考虑,React 可能会把多个 setState() 调用合并成一个调用
@a 所以 “一个 state 依赖其他的 state/props” 的情况可能会出错
1 | // Wrong |
3. State 的更新会被合并
@a 主要指的是 Class 组件中的 setState 方法,如果使用函数组件的 useSate() 方法的回调函数时需要手动合并内容
1 | class Demo extends React.Component { |
State & Props
在 React 哲学 中提到了什么时候不该用 State
元素的 key 只有放在就近的数组上下文中才有意义
一个好的经验法则是:在 map() 方法中的元素需要设置 key 属性。
1 | // 错误做法 |
受控组件/非受控组件
-
使用 State 控制表单输入元素(如果觉得麻烦可以参考 生产方案 )
@q 函数组件如何处理 多个输入 ?只能一个一个 useSate?
-
表单数据将交由 DOM 节点来处理,可以使用 ref 来处理
@a 感觉像是建立一个链接,不过 ref 有使用限制(只能用于 DOM 元素或 Class 组件)
- 不能给 函数组件 设置 ref 属性,具体参考 Refs 与函数组件
- 函数组件内部自由使用,使用 useRef() Hook
状态提升
From
@a 和 向下的数据流 有关
虽然提升 state 方式比双向绑定方式需要编写更多的“样板”代码,但带来的好处是,排查和隔离 bug 所需的工作量将会变少。由于“存在”于组件中的任何 state,仅有组件自己能够修改它,因此 bug 的排查范围被大大缩减了。
Props.children 属性
包含了调用组件时传递的 HTML 内容
1 | function FancyBorder(props) { |
React 哲学
From
React 最棒的部分之一是引导我们思考如何构建一个应用。
将设计好的 UI 划分为组件层级
用 React 创建一个静态版本
- 最好将渲染 UI 和添加交互这两个过程分开。这是因为,编写一个应用的静态版本时,往往要编写大量代码,而不需要考虑太多交互细节;添加交互功能时则要考虑大量细节,而不需要编写太多代码。
- 在构建应用的静态版本时,我们需要创建一些会重用其他组件的组件,然后通过 props 传入所需的数据。props 是父组件向子组件传递数据的方式。即使你已经熟悉了 state 的概念,也完全不应该使用 state 构建静态版本。state 代表了随时间会产生变化的数据,应当仅在实现交互时使用。所以构建应用的静态版本时,你不会用到它。
确定 UI state 的最小(且完整)表示
- 想要使你的 UI 具备交互功能,需要有触发基础数据模型改变的能力。React 通过实现 state 来完成这个任务。
- 为了正确地构建应用,你首先需要找出应用所需的 state 的最小表示,并根据需要计算出其他所有数据。
- 通过问自己以下三个问题,你可以逐个检查相应数据是否属于 state:
- 该数据是否是由父组件通过 props 传递而来的?如果是,那它应该不是 state。
- 该数据是否随时间的推移而保持不变?如果是,那它应该也不是 state。
- 你能否根据其他 state 或 props 计算出该数据的值?如果是,那它也不是 state。
确定 state 放置的位置
React 中的数据流是单向的,并顺着组件层级从上往下传递。哪个组件应该拥有某个 state 这件事,对初学者来说往往是最难理解的部分。尽管这可能在一开始不是那么清晰,但你可以尝试通过以下步骤来判断:
- 找到根据这个 state 进行渲染的所有组件。
- 找到他们的共同所有者(common owner)组件(在组件层级上高于所有需要该 state 的组件)。
- 该共同所有者组件或者比它层级更高的组件应该拥有该 state。
- 如果你找不到一个合适的位置来存放该 state,就可以直接创建一个新的组件来存放该 state,并将这一新组件置于高于共同所有者组件层级的位置。
添加反向数据流
React 通过一种比传统的双向绑定略微繁琐的方法来实现反向数据传递。尽管如此,但这种需要显式声明的方法更有助于人们理解程序的运作方式。
@a 一般来说是在设置 useState 的更新函数或者 this.setState() 方法