Skip to content

Commit 8e5ba63

Browse files
committed
feat(shared/hooks): 新增 useFollowingRef hook
1 parent aae639a commit 8e5ba63

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { renderHook, act } from '@testing-library/react';
2+
import { useFollowingRef } from '@pkg/shared';
3+
import { useState } from 'react';
4+
5+
describe('useFollowingRef', () => {
6+
test('base', () => {
7+
let times = 0;
8+
const hook = renderHook(() => {
9+
const [state, setState] = useState(1);
10+
const followingStateRef = useFollowingRef(state, (v) => v * 2);
11+
times++;
12+
return [followingStateRef, setState] as const;
13+
});
14+
const [value, setValue] = hook.result.current;
15+
16+
expect(value.current).toBe(2);
17+
expect(times).toBe(1);
18+
19+
act(() => setValue(3));
20+
expect(value.current).toBe(6);
21+
expect(times).toBe(2);
22+
});
23+
});

packages/shared/src/hooks/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ export * from './useFollowingState';
2222
export * from './useOnlineStatus';
2323
export * from './useOldValue';
2424
export * from './useChildrenWithRefs';
25+
export * from './useFollowingRef';
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { type MutableRefObject, useRef } from 'react';
2+
import { useWatch } from './useWatch';
3+
4+
/**
5+
* 跟随外部状态的内部状态ref
6+
*/
7+
8+
export function useFollowingRef<T, R>(
9+
state: T,
10+
stateHandler?: (state: T) => R,
11+
): MutableRefObject<R> {
12+
const cb = stateHandler || ((v) => v);
13+
const ref = useRef(cb(state));
14+
useWatch(state, (n) => (ref.current = cb(n)));
15+
return ref as MutableRefObject<R>;
16+
}

0 commit comments

Comments
 (0)