React 开发环境搭建
- 安装 nodejs:官网下载最近 LTS 版本
- 安装集成开发环境:vscode
- 创建 react 项目:
- npx create-react-app project-name
- npm create vite@latest
React 核心语法:JSX
JSX
是 Javascript 和 Html 的缩写,表示在js代码中编写html模版
JSX
不能直接在浏览器中运行,需要bable
进行编码成纯 js 代码
JSX 基础
JSX 识别 js 表达式
JSX 通过{}
语法可以识别 js 表达式
可运行以下 js 表达式:
- 字符串:{“hello world”}(支持模版字符串)
- 变量/js 语句(运算符)
- 函数调用
- 方法调用
列表渲染
|
|
简单条件渲染
对于简单的条件渲染,可通过逻辑与运算符
或者三目运算符
实现
|
|
复杂条件渲染
复杂的条件渲染通过函数
实现
|
|
React 事件绑定
语法
on + 事件名称 = {事件处理函数}
使用事件对象
在事件处理函数
中使用形参e
|
|
传递参数
|
|
React 组件状态管理
给 React 组件添加一个状态变量
,让组件在不同状态下有不同表现
useState 基本使用
通过 useState hook 函数给组件添加一个计数器变量
|
|
useState 注意事项
状态变量是不可变的,只能通过setXXX
函数,并且传入新的值
来改变状态
直接修改状态不能引发视图更新
useState 案例
tabl 栏切换
- 通过 useSate(type)记录 type 状态
- 通过事件回调函数调用状态修改函数,传递被点击项的 type 值为参数
- 通过 classnames 插件优雅实现类名切换
表单受控绑定
通过表单value
属性绑定状态
,通过onChange
事件属性绑定状态同步的函数
|
|
React 获取 Dom 元素
通过 useRef hook 获取 dom 元素从而调用 dom 元素的方法
useRef 基本用法
|
|
注意事项
渲染完毕之后,dom 才可用
useRef 使用场景
- 获取 Dom 元素,调用 Dom 元素的属性或者方法
- 引用一个不需要被渲染的值
- ref 不仅可以引用单个 dom 元素,也可以引用一个列表
- 父组件要获取子组件 Dom 需要 forwardRef 函数做处理,因为 React 框架不允许
组件间通信
父传子
实现步骤:
- 父组件传递数据:在子组件标签上
绑定属性
- 子组件接收数据:子组件通过
props参数
接受数据
props 说明
- props 对象包含了父组件传递过来的
所有数据
- props 对象能传递
任意类型的数据
- props 对象是
只读对象
children 说明
在子组件内部还可以嵌套内容
,同样会给子组件传递数据
,存在 props 对象children属性
上
子传父
- 子组件调用
父组件传递过来的函数
- 通过
函数参数
传递数据给父组件
兄弟组件通信
兄弟组件之间通过状态提升
传递数据
数据跨层通信
- 使用
createContext
函数创建一个上下文对象 Ctx
- 在顶层组件(App)中通过
Ctx.Provider
组件提供数据 - 在底层组件(B)中通过
useContext
hook 获取消费数据
useEffect
useEffect 是一个 React Hook,它允许你 将组件与外部系统同步
参考
useEffect(setup, dependencies?)
|
|
-
setup:处理 Effect 的函数。setup 函数选择性返回一个 清理(cleanup) 函数。当组件被添加到 DOM 的时候,React 将运行 setup 函数。在每次依赖项变更重新渲染后,React 将首先使用旧值运行 cleanup 函数(如果你提供了该函数),然后使用新值运行 setup 函数。在组件从 DOM 中移除后,React 将最后一次运行 cleanup 函数。
-
可选 dependencies:setup 代码中引用的所有响应式值的列表。响应式值包括 props、state 以及所有直接在组件内部声明的变量和函数。如果你的代码检查工具 配置了 React,那么它将验证是否每个响应式值都被正确地指定为一个依赖项。依赖项列表的元素数量必须是固定的,并且必须像 [dep1, dep2, dep3] 这样内联编写。React 将使用 Object.is 来比较每个依赖项和它先前的值。如果省略此参数,则在每次重新渲染组件之后,将重新运行 Effect 函数。如果你想了解更多,请参见 传递依赖数组、空数组和不传递依赖项之间的区别。
不同依赖项的区别
依赖项 | 副作用函数执行时机 |
---|---|
没有依赖项 | 组件初次渲染+组件更新时 |
空数组 | 组件初次渲染 |
特定依赖项 | 组件初次渲染+依赖项变化 |
注意事项
- useEffect 是一个 Hook,因此只能在 组件的顶层 或自己的 Hook 中调用它,而不能在循环或者条件内部调用。如果需要,抽离出一个新组件并将 state 移入其中。
- 如果你 没有打算与某个外部系统同步,那么你可能不需要 Effect。
- 当严格模式启动时,React 将在真正的 setup 函数首次运行前,运行一个开发模式下专有的额外 setup + cleanup 周期。这是一个压力测试,用于确保 cleanup 逻辑“映射”到了 setup 逻辑,并停止或撤消 setup 函数正在做的任何事情。如果这会导致一些问题,请实现 cleanup 函数。
- 如果你的一些依赖项是组件内部定义的对象或函数,则存在这样的风险,即它们将 导致 Effect 过多地重新运行。要解决这个问题,请删除不必要的 对象 和 函数 依赖项。你还可以 抽离状态更新 和 非响应式的逻辑 到 Effect 之外。
- 如果你的 Effect 不是由交互(比如点击)引起的,那么 React 会让浏览器 在运行 Effect 前先绘制出更新后的屏幕。如果你的 Effect 正在做一些视觉相关的事情(例如,定位一个 tooltip),并且有显著的延迟(例如,它会闪烁),那么将 useEffect 替换为 useLayoutEffect。
- 如果你的 Effect 是由一个交互(比如点击)引起的,React 可能会在浏览器重新绘制屏幕之前执行 Effect。通常情况下,这样是符合预期的。但是,如果你必须要推迟 Effect 执行到浏览器绘制之后,和使用 alert() 类似,可以使用 setTimeout。有关更多信息,请参阅 reactwg/react-18/128。
- 即使你的 Effect 是由一个交互(比如点击)引起的,React 也可能允许浏览器在处理 Effect 内部的状态更新之前重新绘制屏幕。通常,这样是符合预期的。但是,如果你一定要阻止浏览器重新绘制屏幕,则需要用 useLayoutEffect 替换 useEffect。
- Effect 只在客户端上运行,在服务端渲染中不会运行。
使用场景
连接到外部系统
|
|
在自定义 Hook 中封装 Effect
Effect 是一种脱围机制
:当你需要“走出 React 之外”或者当你的使用场景没有更好的内置解决方案时,你可以使用它们。如果你发现自己经常需要手动编写 Effect,那么这通常表明你需要为组件所依赖的通用行为提取一些 自定义 Hook。
例如,这个 useChatRoom 自定义 Hook 把 Effect 的逻辑“隐藏”在一个更具声明性的 API 之后:
|
|