如何写css:在tsx或jsx文件中引入.scss/less/css文件
元素的事件绑定:在元素添加属性onXxx,例如<button onClick={handler}>,其中传递的必须是函数,不能是语句调用,如果要定义内联函数,需要将其包装在匿名函数中,比如:
`<button onClick={() => alert(“xx”)}>
Hooks
【重要】Hook需要在非条件语句中使用,调用 Hook 时,例如 useState,仅在组件或另一个 Hook 的顶层被调用才有效。
设置一次state将请求一次重新渲染。
state的状态存储在组件之外
每一次渲染都有一次独属于这次渲染的state快照,同样,不同次渲染内的事件也是各自不同的,在过去某一个渲染中的事件处理函数使用的是那一次渲染所拥有的state快照
只有同一个位置的同一个组件的state才会被保留下来,当从UI树中移除一个组件时,React会销毁它的state(要注意的是此处的位置指的是组件在UI树中的位置,非在jsx代码中的位置)。如果一个组件在UI树中的位置没有变化,但是需要重置它的state,可以为它设置key属性以赋予它一个明确的身份,常用场景:重置表单的state
react内置hooks
useState
useActionState(原为useFormState)可以根据某个表单动作的结果更新state
1 | const [state, formAction, isPending] = useActionState(fn, initialState, permalink) |
useContext
useRef
useEffect
性能Hook
useMemo可以缓存计算结果useCallback 可以缓存函数,在多次渲染中,只要依赖项不变都将返回同样的函数。它的应用场景有:
- 跳过子组件的重新渲染。父组件的重新渲染会递归地渲染所有的子组件,首先将子组件用
memo包裹,当props未发生变化时,子组件会跳过重新渲染,再配合useCallback,使作为props的函数保持不变,就能跳过重新渲染该子组件
useMemo和useCallback常常一同出现,用来做性能优化。useMemo用来缓存
有用的hooks
useReducer 作为useReducer第一个参数的reducer函数命名取自于数组的reduce方法,接收 当前状态 和 action处理方法,返回下一个状态
1 | import { useReducer } from 'react'; |
immer可以简化reducer
ref的使用
当你希望组件记住某些信息,但又不要触发新的渲染,可以使用useRef,useRef会返回一个对象{ current: [initial_data] },例如:
1 | import { useRef } from 'react'; |
使用useRef和使用普通变量的区别:
首先要明确一点:每次触发新的渲染,react组件中的代码都会重新执行一遍。对普通变量x而言,渲染引发的代码重新执行都会产生一个新的x变量引用,而使用useRef定义的变量会返回保留下来的状态值
使用useRef 和 useState的区别:
useRef声明的变量在改变时不会触发重新渲染组件,而使用useState声明的变量在setState时会重新渲染组件。- ref 在渲染过程之外可以任意修改和更新,如
ref.current = ref.current + 1;而state的修改只能通过setState函数,从而触发重新渲染(在某一次具体的快照中state是不可修改的,只能被替换为另一个值)
ref的使用场景通常是:当你的组件需要“跳出” react 并与外部 API 通信。例如:
- 用于存储timeout id;
- 存储和操作dom元素;(常用)
- 存储不需要被用来计算jsx的其他对象;
这些都是不会用于dom渲染展示的场景
Effect的使用
什么是Effect?
大写E开头的Effect是react中定义的一个词,用来描述 由渲染引起的副作用。Effect通常用于暂时跳出react与一些外部系统进行同步,比如 网络请求,浏览器API。Effect的执行时机是 提交结束后/页面更新结束后 这两个
创建一个 Effect
其步骤为:
- 声明一个
Effect - 指定
Effect依赖项 - 必要时添加清理操作
1
2
3
4
5
6
7
8
9
10import {useEffect} from 'react';
function component() {
// useEffect的第二个参数是依赖项数组
// 不传表示每次渲染后运行
// 传入空数组表示只在组件首次挂载时运行
// 传入非空数组则在组件首次挂载 以及 依赖项发生变化时运行
useEffect(() => {
//
}, [])
}
理解Effect
Effect的部分特性可类比到vue中的mounted等生命周期钩子函数,但Effect要更灵活- 与vue不同,
Effect的作用是为了保持组件与外部系统的同步,这种同步可能是由于某些依赖项(state和props这样的响应式数据)的变化,也可能是由于有必要这么做 - 当编写一个
Effect时,要考虑的有两点:1如何开始同步;2如何停止同步(通过返回一个清理函数) - 代码中的每个
Effect应该代表一个独立的同步过程
useEffect 的依赖项是空数组时,回调函数只会执行一次,回调函数会保留初始状态的闭包,如果里面用到state数据,那么使用的会是初始状态的state而不是最新的,解决办法是使用函数式更新,比如;
1 | const [data, setData] = useState([]) |
React的重新渲染
问:如何触发react组件的渲染
答:react组件的初始渲染 和 重新渲染,组件的生命周期分为:触发 - 渲染 - 提交dom,其中提交dom一环在应用真实dom操作之后,还会执行useEffect和useLayoutEffect的内容(useEffect 能获取到更新后绘制完成的真实dom内容,
1 | sequenceDiagram |
什么时候会触发react组件的重新渲染?
答:当且只当state发生变化时,会触发react组件的重新渲染
用vite搭建一个简单的react项目
指令
1 | npm create vite@latest my-react-app -- --template |
模板生成的项目目录如下:
1 | ├── eslint.config.js |
在vite.config.js中用到了@vitejs/plugin-react插件