Skip to content

[Refactor] React Context를 Jotai로 대체하기 #302

@yoopark

Description

@yoopark

Reference

위 PR의 코드 리뷰 과정 중 해결하지 못한 내용이 있어 후속 이슈를 열게 되었습니다.

내용

export function Select({
children,
width,
onValueChange,
defaultValue,
defaultRenderValue,
}: SelectProps) {
const [internalValue, setInternalValue] = useState<string | null>(
defaultValue ?? null,
);
const [renderValue, setRenderValue] = useState(defaultRenderValue ?? '');
const { isOpen, onOpen, onClose, onToggle } = useDisclosure();
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
if (!isOpen) {
return;
}
function handleClickOutside(e: MouseEvent) {
if (!ref.current) {
return;
}
if (ref.current.contains(e.target as Node)) {
return;
}
onClose();
}
document.addEventListener('click', handleClickOutside);
return () => {
document.removeEventListener('click', handleClickOutside);
};
}, [isOpen, onClose]);
return (
<SelectDisclosureContext.Provider
value={{
isOpen,
onOpen,
onClose,
onToggle,
}}
>
<SelectValueContext.Provider
value={{
internalValue,
setInternalValue,
renderValue,
setRenderValue,
onValueChange,
}}
>
<StyledSelect ref={ref} width={width}>
{children}
</StyledSelect>
</SelectValueContext.Provider>
</SelectDisclosureContext.Provider>
);
}

위 파일에서 React Context를 Jotai로 대체하자는 의견이 있었습니다.
이유는 다음과 같습니다.

  1. <Context.Provider value={ ... }>의 방식으로 Provider를 중첩하는 것이 불편하다.
  2. useGet- 훅을 일일이 만드는게 불편하다.

Jotai를 사용하였을 때 예상되는 장점은 다음과 같습니다.

  1. <Provider>를 사용하면 해당 Provider에 atom 상태가 걸리기 때문에, Select마다 atom의 상태를 구분할 수 있다.
  2. Provider 중첩을 하지 않아도 되어 깔끔할 것이다.

하지만, 리팩토링 과정에서 자식 컴포넌트가 렌더링되기 전에 부모 컴포넌트에서 atom의 상태를 변경하는 방법을 모르겠다는 구현상 문제가 있었습니다.

https://jotai.org/docs/core/provider

Jotai의 provider, store 기능에 대하여 더 정확히 알아본 뒤 React Context를 대체할 수 있는 방법을 알아내어 리팩토링을 진행하는 것이 목표입니다.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

Status

📋 Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions