react
react
react 组件渲染的触发条件
- 状态变化:
- 当使用
useState
或useReducer
等 Hook 修改组件的状态时,React 将重新渲染该组件。 - 例如,调用
setState
函数更新状态变量会触发组件的重新渲染。
- 当使用
- 属性变化:
- 当父组件传递给子组件的属性(props)发生变化时,子组件会重新渲染。
- 例如,如果父组件的状态更新导致传给子组件的属性值变化,子组件会根据新的属性重新渲染。
- 强制更新:
- 使用
forceUpdate
方法(通常不推荐使用)可以强制组件重新渲染,即使状态和属性没有变化。
- 使用
基本语法
1 | // 单条消息记录组件 |
路由
1 | $ yarn add react-router-dom |
map()
1 | const products = [ |
类组件:
- 类组件通过扩展
React.Component
或React.PureComponent
类来创建。 - 它们拥有生命周期方法,如
componentDidMount
、componentDidUpdate
等,用于执行组件在不同生命周期阶段的操作。 - 类组件可以持有状态(通过
this.state
)并通过this.setState
方法来更新状态。
函数组件
函数组件是一个纯函数,它接收 props 作为参数并返回 React 元素。
1 | function MyComponent(props) |
函数
在组件内部,函数常用作事件处理器,例如 onClick
、onChange
1 | export default function MyApp() { |
hook
1 | const [count, setCount] = useState(0); |
useContext
允许你订阅 React 上下文,而无需引入嵌套:
1 | function Example() { |
useReducer
允许你用 reducer 管理复杂组件的本地 state:
1 | function Todos() { |
swr
1 |
use effect和swr的渲染区别
1. useEffect
的基本用途
useEffect
是 React 的一个内置钩子,用于在组件渲染后执行副作用操作,如数据请求、订阅或手动更改DOM。它的工作方式如下:
- 无缓存机制:
useEffect
自身不提供数据缓存。每次依赖项改变时,副作用都会重新执行。 - 手动处理依赖:必须手动指定依赖项,以确定何时重新运行效果。
- 控制副作用的执行时机:可以通过清理函数来取消副作用,例如取消网络请求或清理订阅。
2. swr
的高级特性
swr
(由 Vercel 开发,名称来源于 “stale-while-revalidate”)是一个用于数据获取的 React 钩子库。它提供了许多优化的功能,特别适合于数据请求和状态管理:
- 内建缓存和重用机制:
swr
自动缓存每次请求的数据,并在相同的请求再次发起时重用这些数据。这减少了不必要的网络请求和数据加载时间。 - 后台更新:依据 “stale-while-revalidate” 的策略,
swr
会在显示旧数据的同时后台更新数据,一旦新数据到达立即替换,这样用户总是看到尽可能新的数据,同时避免了界面的不必要重渲染。 - 自动重新验证:当窗口重新获得焦点或网络状态改变时,
swr
会自动重新验证数据,确保数据的实时性。 - 更智能的依赖管理:不需要像
useEffect
那样手动声明依赖项,swr
通过请求的键(通常是 URL)自动管理依赖和更新。
context
在典型的 React 应用程序中,数据是通过 props 自上而下(父到子)传递的,但对于应用程序中许多组件所需的某些类型的 props(例如语言环境首选项、UI 主题)来说,这种使用可能会很麻烦。
Context 提供了一种在组件之间共享此类值的方法,而无需在树的每一层显式传递 prop。Context
提供了一种在组件树中共享值(如认证状态、主题、语言设置等)的方法,而无需显式地通过每个组件逐层传递 props。Context
设计的主要目的是为了全局数据(例如用户登录信息、主题或首选语言)的共享,这些数据对于应用内许多组件来说是通用的。
定义风格
1 | export const themes = { |
创建 Context:
- 使用
React.createContext()
创建一个 Context 对象。你可以给它一个默认值。
1 | const MyContext = React.createContext(defaultValue); |
提供 Context 值:
- 使用
<MyContext.Provider>
包裹你的组件树中的一个高层组件。所有在这个 Provider 组件下的子组件都能访问到 Context 的值。 Provider
组件用于将 Context 的值传递给其组件树中的消费者(即Consumer
组件)。它允许你定义 Context 数据的范围,这些数据可以被其下层的所有组件访问。- 定义数据范围:
Provider
接受一个value
属性,该属性可以是任何数据类型,这个值将被提供给所有的下级Consumer
组件。 - 动态数据共享:你可以根据应用的需要,动态改变
Provider
的value
,所有依赖这个 Context 的Consumer
会自动重新渲染,反映最新的数据。
- 定义数据范围:
1 | <MyContext.Provider value={/* some value */}> |
消费 Context 值:
考虑一个应用有多个主题风格,用户可以选择不同的主题风格。你可以创建一个包含当前主题信息的 Context,并在顶层组件(如 App 组件)中提供这个值。然后,在任何子组件中,无论它们位于组件树的哪一层,都可以通过上述任一方法消费这个 Context,根据当前主题进行样式调整。
子组件可以通过两种方式访问 Context:
Context.Consumer
组件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<MyContext.Consumer>
{value => (
<div style={{ backgroundColor: value.background, color: value.foreground }}>
Text with theme colors
</div>
)}
</MyContext.Consumer>
<ThemeContext.Consumer>
{theme => (
<UserContext.Consumer>
{user => (
<ProfilePage user={user} theme={theme} />
)}
</UserContext.Consumer>
)}
</ThemeContext.Consumer>//嵌套useContext
钩子(只能在函数组件中使用):
1
const value = useContext(MyContext);
lazy
允许你延迟加载组件,直到该组件需要第一次被渲染。memo
允许你在 props 没有变化的情况下跳过组件的重渲染。通常useMemo
与useCallback
会一起配合使用。
###好用的组件