响应式系统与 React | 青训营笔记

221 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第7天

React 的历史与应用

前端应用开发
移动原生应用开发
桌面应用开发

React 的设计思路

用原生JS写UI的痛点

  • 状态(自己声明的一些变量)更新,UI不会自动更新,需要手动调用DOM进行更新。
  • 欠缺基本的代码层面的封装和隔离,代码层面没有组件化。
  • UI之间的数据依赖关系,需要手动维护,如果依赖链路长,会一层一层callback,很麻烦。

转换式系统 vs 响应式系统

转换式:就像榨汁机?输入-输出

响应式:就像涟漪?监听-执行

  • 状态更新,UI 自动更新。
  • 前端代码组件化,可复用,可封装。
  • 状态之间的互相依赖关系,不用手动维护,只需声明即可。

组件化设计

  • 组件是组件的组合/原子组件
  • 组件内拥有状态,外部不可见
  • 父组件可将状态传入子组件内部
  • 组件声明了状态和UI的映射(输入状态 → 返回UI)
  • 组件有Props(外)/State(内)两种状态
  • 拼积木:组件可由其他组件拼装而成

组件的状态归属问题

  1. 状态上升

当两个组件共享一个状态时,就需要把状态向上移(至最近的祖宗节点)
但滥用上移,会导致结构混乱
解决方法 → 状态管理库

  1. 状态的局部性

某个状态只需要在某个组件内部维护,不需要共享

注意:
React 是单向数据流,只能父传子,无法子传父。但子组件可以改变父组件状态:父组件传函数 → 子组件执行 → 更新状态。

生命周期

组件的生命周期:挂载mounting,卸载u你mounting,状态改变updating

React(hooks)写法

示例

import React, {useState} from 'react';

function Example() {
    // 声明一个新的状态变量"count"
	const [count,setCount] = useState(0);

	return (
		<div>
			<p>You clicked {count} times</p>
			<button onClick={() => setCount(count+1)}>
				Click me
			</button>
		</div>
	);
}

注意副作用:除了单纯的计算,还要做其它的一些事情
有副作用的函数,可以传入useEffect反作用回去,即 import React, {useState, useEffect} from 'react';
不要在循环,条件或嵌套函数中调用 hook

React 的实现

要解决的问题

  1. JSX不符合JS标准语法

利用转译解决

  1. 返回的JSX发生改变时,如何更新DOM

虚拟DOM:本身不是DOM,但是可以和真实DOM同步改变

  1. State/Props更新时,要重新触发render函数

Diff算法:如何平衡 更新次数少 vs 计算速度快
不同类型的元素——替换
同类型的DOM元素——更新
同类型的组件元素——递归

React 状态管理库

思路:将状态抽离到UI外部进行统一管理(但是会降低组件的复用性)
例:redux xstate mobx recoil

状态机:当前状态,收到外部事件,迁移到下一个状态(如红绿灯每过xx秒进行状态转换)

工具推荐:状态管理库 Modern.js/Reduck(字节)