ReactHooks与ReactRouter:提升性能与实现路由功能
立即解锁
发布时间: 2025-09-04 01:47:15 阅读量: 6 订阅数: 31 AIGC 


React 18设计模式精要
### React Hooks与React Router:提升性能与实现路由功能
#### 1. React Hooks的性能优化
在React开发中,性能优化是一个重要的课题。我们可以通过一些Hooks来优化组件的性能,下面介绍几个常用的Hooks。
##### 1.1 useMemo的使用
当看到控制台警告 `react-hooks/exhaustive-deps` 时,需要将相关依赖添加到数组中。例如,过滤待办事项列表时:
```typescript
const filteredTodoList = useMemo(() => todoList.filter((todo: Todo) => {
console.log('Filtering...')
return todo.task.toLowerCase().includes(term.toLowerCase())
}), [term, todoList])
```
这里使用 `useMemo` 来记忆计算结果,避免不必要的重复计算。
##### 1.2 useCallback的使用
在添加删除任务功能时,最初的 `handleDelete` 函数会在每次重新渲染时重新生成,导致性能问题。
```typescript
// 最初的实现
const handleDelete = (taskId: number) => {
const newTodoList = todoList.filter((todo: Todo) => todo.id !== taskId)
setTodoList(newTodoList)
}
```
使用 `useCallback` 可以记忆函数定义,避免重新定义:
```typescript
const handleDelete = useCallback((taskId: number) => {
const newTodoList = todoList.filter((todo: Todo) => todo.id !== taskId)
setTodoList(newTodoList)
}, [todoList])
```
这样,当输入内容时,组件的渲染次数会显著减少,性能得到提升。
##### 1.3 作为useEffect参数的函数记忆
当在 `useEffect` 中传递函数作为参数时,也可能会遇到性能问题。例如:
```typescript
const printTodoList = () => {
console.log('Changing todoList', todoList)
}
useEffect(() => {
printTodoList()
}, [todoList, printTodoList])
```
这里会出现警告,需要使用 `useCallback` 来解决:
```typescript
const printTodoList = useCallback(() => {
console.log('Changing todoList', todoList)
}, [todoList])
```
##### 1.4 常用Hooks总结
| Hook | 作用 | 使用场景 |
| ---- | ---- | ---- |
| memo | 记忆组件,当props改变时重新记忆,避免重新渲染 | 组件频繁渲染 |
| useMemo | 记忆计算值,用于计算属性和繁重的处理 | 有复杂计算的场景 |
| useCallback | 记忆函数定义,避免每次渲染时重新定义 | 函数作为效果参数传递或通过props传递给记忆化组件时 |
#### 2. useReducer Hook的理解
`useReducer` 与Redux有相似之处,但也有一些区别。Redux提供中间件和包装器,而 `useReducer` 只提供一个 `dispatch` 方法来调度普通对象作为动作,并且默认没有存储。
##### 2.1 创建基本应用
首先,创建一个新的React应用:
```bash
npx create-vite reducer --template react-ts
```
然后,删除 `src` 文件夹中除 `App.tsx` 和 `index.tsx` 之外的所有文件。
##### 2.2 实现Notes应用
定义类型:
```typescript
type Note = {
id: number
note: string
}
type Action = {
type: string
payload?: any
}
type ActionTypes = {
ADD: 'ADD'
UPDATE: 'UPDATE'
DELETE: 'DELETE'
}
const actionType: ActionTypes = {
ADD: 'ADD',
DELETE: 'DELETE',
UPDATE: 'UPDATE'
}
```
创建初始笔记:
```typescript
const initialNotes: Note[] = [
{
id: 1,
note: 'Note 1'
},
{
id: 2,
note: 'Note 2'
}
]
```
定义reducer函数:
```typescript
const reducer = (state: Note[], action: Action) => {
switch (action.type) {
case actionType.ADD:
return [...state, action.payload]
case actionType.DELETE:
return state.filter(note => note.id !== action.payload)
case actionType.UPDATE:
const updatedNote = action.payload
return state.map((n: Note) => n.id === updatedNote.id ? updatedNote : n)
default:
return state
}
}
```
在 `Notes` 组件中使用 `useReducer`:
```typescript
const Notes = () => {
const [notes, dispatch] = useReducer(reducer, initialNotes)
const [note, setNote] = useState<string>('')
const handleSubmit = (e: ChangeEvent<HTMLInputElement>) => {
e.preventDefault()
const newNote = {
id: Date.now(),
note
}
dispatch({ type: actionType.ADD, payload: newNote })
}
return (
<div>
<h2>Notes</h2>
<ul>
{notes.map((n: Note) => (
<li key={n.id}>
{n.note} {' '}
<button onClick={() => dispatch({ type: actionType.DELETE, payload: n.id })}>
X
</button
```
0
0
复制全文
相关推荐









