Skip to content

Commit

Permalink
feat(useHistoryTravel): add limit history length parameter (#1921)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alt-er committed Oct 18, 2022
1 parent 4d693e0 commit ae9cc20
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 10 deletions.
47 changes: 47 additions & 0 deletions packages/hooks/src/useHistoryTravel/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,51 @@ describe('useHistoryTravel', () => {
expect(hook.result.current.backLength).toEqual(0);
expect(hook.result.current.forwardLength).toEqual(0);
});

it('should work without max length', async () => {
const hook = renderHook(() => useHistoryTravel());
expect(hook.result.current.backLength).toEqual(0);
for (let i = 1; i <= 100; i++) {
act(() => {
hook.result.current.setValue(i);
});
}
expect(hook.result.current.forwardLength).toEqual(0);
expect(hook.result.current.backLength).toEqual(100);
expect(hook.result.current.value).toEqual(100);
});

it('should work with max length', async () => {
const hook = renderHook(() => useHistoryTravel(0, 10));
expect(hook.result.current.backLength).toEqual(0);
for (let i = 1; i <= 100; i++) {
act(() => {
hook.result.current.setValue(i);
});
}
expect(hook.result.current.forwardLength).toEqual(0);
expect(hook.result.current.backLength).toEqual(10);
expect(hook.result.current.value).toEqual(100);

act(() => {
hook.result.current.go(-5);
});
expect(hook.result.current.forwardLength).toEqual(5);
expect(hook.result.current.backLength).toEqual(5);
expect(hook.result.current.value).toEqual(95);

act(() => {
hook.result.current.go(5);
});
expect(hook.result.current.forwardLength).toEqual(0);
expect(hook.result.current.backLength).toEqual(10);
expect(hook.result.current.value).toEqual(100);

act(() => {
hook.result.current.go(-50);
});
expect(hook.result.current.forwardLength).toEqual(10);
expect(hook.result.current.backLength).toEqual(0);
expect(hook.result.current.value).toEqual(90);
});
});
33 changes: 33 additions & 0 deletions packages/hooks/src/useHistoryTravel/demo/demo3.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* title: Limit maximum history length
* desc: Limit the maximum number of history records to avoid excessive memory consumption.
*
* title.zh-CN: 限制历史记录最大长度
* desc.zh-CN: 限制最大历史记录数量,避免过度占用内存。
*/

import { useHistoryTravel } from 'ahooks';
import React from 'react';

export default () => {
const maxLength = 3;
const { value, setValue, backLength, forwardLength, back, forward } = useHistoryTravel<string>(
'',
maxLength,
);

return (
<div>
<div>maxLength: {maxLength}</div>
<div>backLength: {backLength}</div>
<div>forwardLength: {forwardLength}</div>
<input value={value || ''} onChange={(e) => setValue(e.target.value)} />
<button disabled={backLength <= 0} onClick={back} style={{ margin: '0 8px' }}>
back
</button>
<button disabled={forwardLength <= 0} onClick={forward}>
forward
</button>
</div>
);
};
13 changes: 9 additions & 4 deletions packages/hooks/src/useHistoryTravel/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ A hook to manage state change history. It provides encapsulation methods to trav

<code src="./demo/demo2.tsx" />

### Limit maximum history length

<code src="./demo/demo3.tsx" />

## API

```typescript
Expand All @@ -28,14 +32,15 @@ const {
go,
back,
forward
} = useHistoryTravel<T>(initialValue?: T);
} = useHistoryTravel<T>(initialValue?: T, maxLength: number = 0 );
```

### Params

| Property | Description | Type | Default |
| ------------ | ---------------------- | ---- | ------- |
| initialValue | Optional initial value | `T` | - |
| Property | Description | Type | Default |
| ------------ | ------------------------------------------------------------------------------------------------------------------------- | -------- | ----------- |
| initialValue | Optional initial value | `T` | - |
| maxLength | Optional limit the maximum length of history records. If the maximum length is exceeded, the first record will be deleted | `number` | 0 unlimited |

### Result

Expand Down
12 changes: 10 additions & 2 deletions packages/hooks/src/useHistoryTravel/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const split = <T>(step: number, targetArr: T[]) => {
};
};

export default function useHistoryTravel<T>(initialValue?: T) {
export default function useHistoryTravel<T>(initialValue?: T, maxLength: number = 0) {
const [history, setHistory] = useState<IData<T | undefined>>({
present: initialValue,
past: [],
Expand All @@ -54,10 +54,18 @@ export default function useHistoryTravel<T>(initialValue?: T) {
};

const updateValue = (val: T) => {
const _past = [...past, present];
const maxLengthNum = isNumber(maxLength) ? maxLength : Number(maxLength);
// maximum number of records exceeded
if (maxLengthNum > 0 && _past.length > maxLengthNum) {
//delete first
_past.splice(0, 1);
}

setHistory({
present: val,
future: [],
past: [...past, present],
past: _past,
});
};

Expand Down
13 changes: 9 additions & 4 deletions packages/hooks/src/useHistoryTravel/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ nav:

<code src="./demo/demo2.tsx" />

### 限制历史记录最大长度

<code src="./demo/demo3.tsx" />

## API

```typescript
Expand All @@ -28,14 +32,15 @@ const {
go,
back,
forward
} = useHistoryTravel<T>(initialValue?: T);
} = useHistoryTravel<T>(initialValue?: T, maxLength: number = 0);
```

### Params

| 参数 | 说明 | 类型 | 默认值 |
| ------------ | ------------ | ----- | ------ |
| initialValue | 可选,初始值 | `any` | - |
| 参数 | 说明 | 类型 | 默认值 |
| ------------ | --------------------------------------------------------- | -------- | -------- |
| initialValue | 可选,初始值 | `any` | - |
| maxLength | 可选,限制历史记录最大长度,超过最大长度后将删除第一个记录 | `number` | 0 不限制 |

### Result

Expand Down

0 comments on commit ae9cc20

Please sign in to comment.