Skip to content

Commit

Permalink
docs: add advanced tutorial
Browse files Browse the repository at this point in the history
  • Loading branch information
Okabe-Rintarou-0 committed Jan 26, 2025
1 parent 2891b3b commit 9522c38
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 106 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,40 @@ return <Card title='案例1' extra={<Button onClick={mutate}>刷新</ Button>}
你可以在“案例2”中体验两种写法的区别。这里我们使用的是一个公开的 api(https://dogapi.dog/docs/api-v2) 。
当然,随着业务的发展,你可能还会有更多的需求,在这个 useData 上面新增更多的状态和配置。既然如此,**何必自己造轮子呢**?你完全可以用 `useSWR + axios` 这套方案,详见:useSWR 的官方文档:https://swr.vercel.app/zh-CN/docs/data-fetching ,此处不再赘述😁。
当然,随着业务的发展,你可能还会有更多的需求,在这个 useData 上面新增更多的状态和配置。既然如此,**何必自己造轮子呢**?你完全可以用 `useSWR + axios` 这套方案,详见:useSWR 的官方文档:https://swr.vercel.app/zh-CN/docs/data-fetching ,此处不再赘述😁。
## 使用 useImmer 简化 state 更新
安装:
```shell
yarn add immer use-immer
```
假设你有这样的一个类型的数据:
```typescript
interface TagType {
color: string;
text: string;
}
```
你希望渲染出一堆 tags,并且按下按钮修改其中一个 tag 的 text,如果用原生的 `useState` 会这样写:
```typescript
const [tags, setTags] = useState<TagType[]>(generateTestTags());
const modify = () => {
tags[randIndex].text = 'changed';
setTags([...tags]);
};
```
由于 `useState` 监听的是一个数组(引用类型),所以浅拷贝是无法产生页面重渲染的,此处必须传递深拷贝,修改数组的地址,引发页面重渲染。然而,显而易见,这种方式一旦数组长度达到一定程度,性能开销将无法忽视。例如,在本案例中,我们渲染了 10000个标签。每次修改的时候,都会对这个大小为 10000 的数据进行深拷贝。
`useImmer` 则允许我们直接修改数组/对象的字段,无需进行深拷贝,节省性能并提升代码可读性:
```typescript
setOptTags(tags => { tags[randIndex].text = 'changed' });
```
38 changes: 2 additions & 36 deletions advanced_tutorial/docs/性能调优秘籍.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,6 @@ const cnt = doSomethingSlowly();
你可以通过我们给定的案例3中优化后的结果来更好地理解这一点。
## 使用 useImmer 提升更新效率
## 使用 useDebounceFn 限流回调函数
安装:
```shell
yarn add immer use-immer
```
假设你有这样的一个类型的数据:
```typescript
interface TagType {
color: string;
text: string;
}
```
你希望渲染出一堆 tags,并且按下按钮修改其中一个 tag 的 text,如果用原生的 `useState` 会这样写:
```typescript
const [tags, setTags] = useState<TagType[]>(generateTestTags());
const modify = () => {
tags[randIndex].text = 'changed';
setTags([...tags]);
};
```
由于 `useState` 监听的是一个数组(引用类型),所以浅拷贝是无法产生页面重渲染的,此处必须传递深拷贝,修改数组的地址,引发页面重渲染。然而,显而易见,这种方式一旦数组长度达到一定程度,性能开销将无法忽视。例如,在本案例中,我们渲染了 10000个标签。每次修改的时候,都会对这个大小为 10000 的数据进行深拷贝。通过性能工具,我们可以发现这一修改过程将耗费几百毫秒。
`useImmer` 则允许我们直接修改数组/对象的字段,无需进行深拷贝,极大地节省性能并提升代码可读性:
```typescript
setOptTags(tags => { tags[randIndex].text = 'changed' });
```
你可以通过以下视频对比优化前后的性能差距:
https://github.com/user-attachments/assets/42b7cd5c-4e2e-4dc5-ae93-32a160c120d7
详见:https://ahooks.js.org/hooks/use-debounce-fn/
2 changes: 0 additions & 2 deletions advanced_tutorial/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import { Space } from 'antd'
import Case1 from './cases/case1'
import Case2 from './cases/case2'
import Case3 from './cases/case3'
import Case4 from './cases/case4'

function App() {
return <Space style={{ width: "100%" }} direction='vertical'>
<Case1 />
<Case2 />
<Case3 />
<Case4 />
</Space>
}

Expand Down
67 changes: 0 additions & 67 deletions advanced_tutorial/src/cases/case4.tsx

This file was deleted.

0 comments on commit 9522c38

Please sign in to comment.