Skip to content

Commit

Permalink
feat(shared/hooks): useStateRef
Browse files Browse the repository at this point in the history
  • Loading branch information
mengxinssfd committed Dec 18, 2023
1 parent 5783938 commit 58756da
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
29 changes: 29 additions & 0 deletions packages/shared/src/hooks/__tests__/useStateRef.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { renderHook, act } from '@testing-library/react';
import { useStateRef } from '@pkg/shared';
import { useRef } from 'react';

describe('useStateRef', () => {
test('basic', () => {
let renderTimes = 0;
const hook = renderHook(() => {
renderTimes++;
const ref = useRef<number>(1);
return [...useStateRef(ref.current), ref] as const;
});
const [value, setValue, forceUpdate, ref] = hook.result.current;

expect(renderTimes).toBe(1);
expect(value.current).toBe(1);

act(() => setValue(2));
expect(value.current).toBe(2);
expect(ref.current).toBe(1);

act(() => {
ref.current = 3;
forceUpdate();
});
expect(ref.current).toBe(3);
expect(value.current).toBe(3);
});
});
1 change: 1 addition & 0 deletions packages/shared/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ export * from './useEventListenerOnMounted';
export * from './useBeforeDestroy';
export * from './useValueWithPrev';
export * from './useUniqueRoot';
export * from './useStateRef';
22 changes: 22 additions & 0 deletions packages/shared/src/hooks/useStateRef.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useForceUpdate } from './useForceUpdate';
import { useCallback, useRef } from 'react';
import { useWatch } from './useWatch';

export function useStateRef<V>(
state: V,
): [
stateRef: React.MutableRefObject<V>,
setStateRef: (value: V) => void,
forceUpdate: () => void,
] {
const forceUpdate = useForceUpdate();
const stateRef = useRef(state);
useWatch(state, (n) => (stateRef.current = n));

const setValue = useCallback((value: V) => {
stateRef.current = value;
forceUpdate();
}, []);

return [stateRef, setValue, forceUpdate];
}

0 comments on commit 58756da

Please sign in to comment.