썸네일 만들어주신 보리님 감사합니다.
별 건 아니지만 시리즈로는 오랜만에 포스팅하네요.
여러 리엑트 컴포넌트에서 특정 돔을 조회해야 하는 경우가 있었습니다.
예를 들어 이런 상황입니다.
좌측 1번, 2번 컴포넌트의 특정 버튼을 누를 시 우측 컴포넌트 내부에 있는 돔의 위치를 변경시켜야 합니다.
이럴 때는 어떻게 해야 할까요?
두 가지 시나리오가 있을 수 있습니다.
리엑트에서 돔을 직접 조작하는 경우는 많지 않으니 상태 값을 조작하는게 맞을까요?
꼭 그렇지는 않습니다.
1번 시나리오로 가봅시다.
동그라미는 상태입니다. 1,2,3번 컴포넌트가 우측 컴포넌트의 상태 값을 조작하면 이 컴포넌트에서 결국 저 돔을 조작해야 합니다.
그런데 말입니다.
저 상태 값은 어떻게 좌측 컴포넌트에서 업데이트 시킬 수 있을까요?
두 가지 방법이 있습니다.
결국 1,2번과 우측 컴포넌트를 포함하는 상위 컴포넌트에서 상태 값을 만들어서 참조시켜야 합니다.
복잡하네요.
그래서 저는 상태값을 업데이트 하지 않고 1,2번 컴포넌트에서 돔을 직접 조작할 수 있게 만들겁니다.
근데 이렇게 하려면 우측 컴포넌트에서 돔이 마운트 될 때까지 기다린 다음에 1,2번 컴포넌트에서 해당 값을 참조할 수 있어야 합니다.
두둥!
저는 Jotai를 사용하고 있는데요, jotai에는 atom이라는 primitive type이 있습니다. useEffect 대신에 atom이 어떻게 돔을 참조하게 할 수 있을 지 고민이 되었는데요.
그래서 물어봤습니다.
누구한테?
Jotai 만든 사람한테.
https://github.com/pmndrs/jotai/discussions/1488#discussioncomment-3942031
정확한 번역은 아닙니다.
안녕하세요, 저는 useEffect를 별로 좋아하지 않는데요, 돔에 대한 ref를 얻을 수 있는 시점에 맞춰서 atom을 업데이트하려면 어떻게 해야 할까요
저도 별로 안좋아해요. 근데 이 경우 useEffect나 useCallback을 써야 할 것으로 보이네요.
useEffect 안쓰고 싶은데 써야 할 것 같네요.
그러게요 써야 할 것 같네요.
정 쓰기 싫으면 atom의 onMount 사용해보실 수 있겠네요.
근데 useEffect 쓰는게 가독성에는 더 나을 수 있겠네요.
제가 useEffect를 안쓰는 이유는 가독성이 안좋아지기 때문입니다.
이렇게 써볼 수 있겠네요.
dai-shi san이 제안한대로 atom의 onMount를 사용해 useEffect를 대체해봅시다.
atom onMount는 atom이 처음으로 읽어질 때 실행됩니다.
mountingAtom 은 아래 코드에 useMemo를 사용해 a 라는 atom을 참조합니다.
그리고 useAtom을 사용해 바로 아래 줄에서 실행됩니다.
실행될 때 ref 에 대한 정보가 이미 div ref props를 통해서 존재하기 때문에
외부에 있는 htmlRefAtom에 div dom 정보를 세팅할 수 있게 됩니다.
const htmlRefAtom = atom(null)
const Component = () => {
const ref = useRef()
const mountingAtom = useMemo(() => {
const a = atom(
(get) => get(htmlRefAtom),
(get, set, arg) => set(htmlRefAtom, arg)
)
a.onMount = (set) => {
set(ref.current)
}
return a
}, [])
useAtom(mountingAtom)
return (
<div ref={ref}>Hello</div>
)
}
아주 괜찮은 방법이네요.
jotai와 side effect를 결합 할때 한 가지 방법이 될 것 같습니다.
좋은 참조가 되었길 바랍니다.
구독자 100명이 되었습니다.
기다리고 있었습니다. 제대로 모시겠습니다.