这是我参与「第五届青训营」伴学笔记创作活动的第 6 天
| 本堂课重点内容
本堂课重点讲述了React的发展和设计思路。
| React的发展与应用
React 起源于 Facebook 的内部项目,用来架设Instagram 的网站。由于使用效果极佳,就被决定在2013年5月开源了。
React的常见应用场景
- 前端应用开发:Facebook、Instagram、Netfix网页版等
- 移动原生应用开发:Instagram、Discord、Oculus等
- 桌面应用开发:结合Electron
| React的设计思路
-
定位编程痛点:UI更新
-
响应式与转换式系统
-
响应式编程:事件 → 执行既定的回调 → 状态变更 →UI更新
-
组件化
- 组件是组件的组合/原子组件
- 组件内拥有状态,外部不可见
- 父组件可将状态传入组件内部
-
状态归属
状态归属于两个节点向上寻找到的最近的祖宗节点
思考:
- React是单向数据流, 还是双向数据流?
- 单向。
- 如何解决状态不合理上升的问题?
- 组件的状态改变后,如何更新DOM ?
-
生命周期
React组件的生命周期可分成三个状态:
- Mounting(挂载):已插入真实 DOM
- Updating(更新):正在被重新渲染
- Unmounting(卸载):已移出真实 DOM
| React Hooks的写法与React实现
- 指令式编程
- 声明式编程
- 响应式编程
注意:不要在循环,条件或嵌套函数中调用Hook
useState()
const [size, setSize] = useState({ width: 0, height: 0})
const handleContainerResize = ({ width, height }) => {
setSize({width, height})
}
const [name, setName] = useState("zhangsan");
const [value, setValue] = useState(0)
const change = (event) => {
setName(event.target.value)
}
return (
<div>
<div>{value}</div>
<button onClick={() => setValue(value + 1)} >加一</button>
<input onChange={change} value={name}/>
<div/>
)
useEffect()
函数的副作用就是函数除了返回值外对外界环境造成的其它影响,大致可以分为两类:
-
调用浏览器的API
-
发起获取服务器数据的请求
-
useEffect与依赖项:
useEffect(() => {...})每次组件渲染都执行useEffect(() => { return () => {...} }, [])组件第一次渲染执行,组件移除时触发clean函数useEffect(() => { return () => {...} }, [dep])dep改变才会执行,组件重新渲染前触发clean函数
-
useEffect与useLayoutEffect
- useEffect 的函数会在组件渲染到屏幕之后执行
- useLayoutEffect则是在DOM结构更新后、渲染前执行,相当于有一个防抖效果
useRef()
useRef是用来在组件不同渲染之间共用一些数据的,作用与类组件中this赋值相似。
- 赋值:
const life = useRef(null) - 修改:
life.current = "Life is worth lliving."
useCallBack()
const memoizedCallback = useCallback(callback, dependencies)
- 参数1是一个回调函数,是需要被记住的函数
- 参数2是参数1中函数的依赖项,只有dependencies数组里面的元素的值发生变化时useCallback才会返回新定义的函数,否则useCallback都会返回之前定义的函数
useMemo()
useMemo与useCallback的作用类似,区别是useMemo允许记住任何类型的变量(函数、对象...)
useContext()
父子组件传值、全局共享数据
- 导入
createContext,使用createContext创建Context对象- 在顶层组件通过
Provider提供数据- 在底层组件通过
useContext函数获取数据
useReducer()
useReducer允许我们在函数组件里面像使用redux一样通过reducer和action来管理我们组件状态的变换
const [state, dispatch] = useReducer(reducer, initialArg, init)
- reducer - 状态转换函数,(currentState, action) => newState,接收当前的state和当前dispatch的action为参数,然后返回下一个state。
- initialArg - 如果调用者没有提供第三个init参数,这个参数代表的是这个reducer的初始状态;如果init参数被指定,initialArg会被作为参数传进init函数来生成初始状态。
- init - 生成初始状态函数,(initialArg) => initialState,接收useReducer的第二个参数initialArg作为参数,并生成一个初始状态initialState。
diff算法规则:
- 不同类型元素 -- 替换
- 相同类型的DOM元素 -- 更新
- 相同类型的组件元素 -- 递归
| React状态管理库与应用级框架科普
React状态管理库:(核心)将状态抽离到UI外部进行统一管理
- redux
- xstate
- mobx
- recoil
- 字节开发 - modern.js/reduck
状态机:当前状态,收到外部事件,迁移到下一个状态
应用级框架:
- next.js:稳定,开发体验好,支持Unbundled Dev,SWC等,其同样有Serverless一键部署平台帮助开发者快速完成部署。
- modern.js:字节跳动Web Infra 团队研发的全栈开发框架,内置了很多开箱即用的能力与最佳实践,可以减少很多调研选择工具的时间。
- Blitz:无API思想的全栈开发框架,开发过程中无需写API调用与CRUD逻辑,适合前后端紧密结合的小团队项目。
个人总结
本次课是对React的一个基础引入,不仅介绍了React的发展、应用场景,还介绍了一些React的钩子函数、状态管理库等,在学习完基础的React之后,我们可以更深一步学习一些基于React的应用级框架。