-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Implement Menubar & Toast component with storybook #24
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다! 코드에서 가독성과 접근성, 성능까지 고려한다는 점이 많이 느껴지는 것 같습니다!!
많이 배워갑니다 ㅎㅎㅎ 👍🏻
parameters: { | ||
layout: 'centered', | ||
}, | ||
} satisfies Meta<typeof Menubar>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 satisfies 배워갑니다
const contextValue = { | ||
selectedMenu, | ||
isOpen, | ||
setIsOpen, | ||
onOpenMenu: () => setIsOpen(true), | ||
onSelectedMenu, | ||
onCloseMenu, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이렇게 해서 넘기니까 가독성이 좋네요 👍🏻
useEffect(() => { | ||
if (!open) wasKeyboardTriggerOpenRef.current = false; | ||
}, [open]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
혹시 여기 의존성배열에 있는 open은 어디에서 가져오는 건가요?
const extractText = useCallback( | ||
(child: ReactNode): string => { | ||
if (typeof child === 'string') { | ||
return child; | ||
} | ||
return ''; | ||
}, | ||
[selectedMenu], | ||
); | ||
|
||
const menuName = extractText(children); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 props.children으로 바로 사용했었는데 😅
이렇게 children를 이용해서 구체적으로 메뉴이름을 추출해서 변수로 사용하는 방법 좋은 것 같습니다 👍🏻👍🏻👍🏻
); | ||
|
||
const menuName = extractText(children); | ||
const isActive = selectedMenu === menuName; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isActive도 명시적이고 좋네요
triggerId: useId(), | ||
triggerRef, | ||
contentId: useId(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trigger와 content에 고유한 id를 부여하는 방법도 좋은 것 같아요 👍🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
radix ui를 참고했는데 useId 사용 하더라구요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏻👍🏻👍🏻
export const ToastProvider = ({ children }: { children: ReactNode }) => { | ||
const [toastList, setToastList] = useState<ToastContent[]>([]); | ||
const value = useMemo( | ||
() => ({ toastList, setToastList }), | ||
[toastList, setToastList], | ||
); | ||
|
||
return ( | ||
<ToastContext.Provider value={value}>{children}</ToastContext.Provider> | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shadcn은 최상단에 Provider없이 Toaster(== 거정님 코드에서 ToastContainer)만 사용하길래 어떻게 사용하는지 코드를 살펴봤는데, 아래 코드처럼 아예 전역변수를 사용하는 것 같더라구요. (scope 관련한 코드가 있는 것 같기도한데 파악하지는 못했습니다.)
// useToast.tsx
let memoryState: State = { toasts: [] };
const listeners: Array<(state: State) => void> = [];
const useToast = () => {
const [state, setState] = useState<State>(memoryState);
useEffect(() => {
listeners.push(setState);
return () => {
const index = listeners.indexOf(setState);
if (index > -1) {
listeners.splice(index, 1);
}
};
}, [state]);
return {
...state, // toasts
toast,
};
};
export { useToast, toast };
전역변수를 쓰면 렌더링 사이클에 얽매이지 않아 퍼포먼스 면에서 오버헤드가 적을 수 있지만,
context provider를 쓰는게 1. 명확한 구조이고 2. 전역 변수가 아니라서 예측가능하다는 점에서 협업시에 더 좋은 것 같다고 생각했습니다.
그리고 react-toastify도 provider를 사용하지 않는데, 이를 간략하게 구현한 글이 있어 공유합니다. toast와 toastContainer 사이에 eventManager를 두어 동작하는 방식이고, toastlist는 useToastContainer 내에서 Map으로 관리하더라구요.
https://www.milk717.com/gomterview-3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
공유 감사합니다!! 한번 찾아보겠습니다!
|
Motivation 🤔
Key Changes 🔑
To Reviews 🙏🏻