Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions packages/lib/src/hooks/useShallowState.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
import { useState } from "react";
import { useRef, useState } from "react";
import { useCallback } from "./useCallback";
import { shallowEquals } from "../equals";

export const useShallowState = <T>(initialValue: Parameters<typeof useState<T>>[0]) => {
// useState를 사용하여 상태를 관리하고, shallowEquals를 사용하여 상태 변경을 감지하는 훅을 구현합니다.
return useState(initialValue);
const [state, _setState] = useState<T | undefined>(initialValue);
const curState = useRef<T>(state); //setState 메모이제이션용. state를 의존해서는 안됨. -> 매번 리렌더링 됨

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useRef 를 사용해 state를 저장한 이유가 매번 리렌더링 되는걸 막기 위해서인가요!? 매번 리렌더링이 되는 이유가 궁금합니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 만든 setState 함수에서 state를 직접 참조하면, state가 변경될 때마다 의존성 배열에 state가 들어가게 되고, 그 결과 state가 업데이트될 때마다 setState가 매번 새로 생성됩니다.
그래서 useRef를 사용해 상태를 관리함으로써 setState 함수가 불필요하게 재생성되는 걸 막고 동시에 최신 상태에 안정적으로 접근할 수 있게 했습니다.

제가 '리렌더링'이라고 표현을 좀 잘못 사용한 것 같아요!
리렌더링을 막기 위함이 아니라 setState함수가 매번 재생성되는 걸 막기 위해 ref를 썼다고 보심 될 것 같아요


curState.current = state;

const setState = useCallback((updater: T | ((prev: T) => T)) => {
const newValue =
typeof updater === "function" ? (updater as (prev: T | undefined) => T)(curState.current) : updater;

if (!shallowEquals(newValue, curState.current)) {
_setState(newValue);
}
}, []);

return [state, setState];
};