지금 진행중인 포트폴리오 생성 사이트는, 포트폴리오를 생성하기 위해 여러 템플릿의 조합으로 하나의 포트폴리오가 만들어 집니다.
이 템플릿은 각각 템플릿에 맞는 정보를 입력할 수 있게 구성되어 있는데, 최종적으로 포트폴리오를 생성하기 위해서는 템플릿의 데이터를 모두 모아 최상단에서 관리할 필요가 있습니다.
그러나 최상단에서 useState
를 통해 데이터를 관리하게 되면, 템플릿의 데이터가 변경될 때마다 너무나 많은 요소들에서 re-rendering
이 발생하게 됩니다.
이러한 문제점을 해결하고자, 최상위에서 데이터를 수집할 때, re-rendering
이 발생하지 않도록 처리하려 합니다.
이 현상을 해결하기 위해 mutable
한 값을 관리할 수 있는 hook
, useRef
를 이용해 데이터를 관리하려 합니다.
먼저 useRef
는 useState
와 달리 값이 변경되어도 render
를 유발하지 않으며, 일반 변수와 달리, state
가 변경되어도 값이 그대로 유지됩니다.
const portfolio = useRef({
header: {
title:'Portfolio Creator'
},
section: [...data]
})
위와 같은 형태로 데이터를 모아줍니다.
portfolio
를 관리하기 위한 setter
와 getter
를 만들어 줍니다.
// getter
const getPortfolio = useCallback(() => portfolio.current, [])
// setter
const setPortfolio = useCallback((callback) => {
portfolio.current = callback(portfolio.current);
}, []);
위 함수를 통해 portfolio
에 접근할 수 있게 되었습니다.
그런데 데이터를 모으고 있는 최상위 컴포넌트를 제외한 다른 컴포넌트에서 portfolio
의 데이터를 수정하거나 필요한 상황이 존재합니다.
다른 컴포넌트에서는 setter
와 getter
에 접근할 수 없기에, 최상위 컴포넌트를 Context
로 만들어 다른 컴포넌트에서 setter
와 getter
에 접근할 수 있도록 해줍니다.
// index.page.js
const CreateContext = createContext(null)
export const Create = ({children}) => {
const portfolio = useRef({})
const getPortfolio = () => {}
const setPortfolio = () => {}
// ... 생략
return (
<CreateContext.Provider value={{ getPortfolio, setPortfolio }}>
{children}
</CreateContext.Provider>
)
}
export const useCreateContext = () => {
return useContext(CreateContext);
}
위와 같은 구성을 통해 다른 컴포넌트에서 useCreateContext
를 통해 접근할 수 있게 되었습니다.
위 과정을 통해 re-rendering
없이 데이터를 관리할 수 있게 되었습니다.
그렇지만 템플릿을 추가하는 등, re-rendering
을 발생시켜 화면 구성의 변경이 필요한 상황도 있습니다.
이러한 상황에 대응하기 위해, requestRender
라는 함수를 통해 고의적으로 re-rendering
을 발생시킬 수 있게 하려 합니다.
// index.page.js
export const Create = ({children}) => {
// ... 생략
const [, setRenderHash] = useState('')
const requestRender = useCallback(() => {
setRenderHash(JSON.stringify(portfolio.current))
}, [])
return (
<CreateContext.Provider value={{ getPortfolio, setPortfolio, requestRender }}>
{children}
</CreateContext.Provider>
)
}
위와 같이 portfolio
를 해쉬값으로 변환해, 템플릿이 추가되는 등 해쉬값에 변화가 있으면 re-rendering
을 발생시키는 함수를 만들었습니다.
위 과정을 통해 re-rendering
없이 최상단에서 템플릿의 데이터들을 취합할 수 있게 되었습니다.
그렇지만 이런 구조가 올바른 방법인지에 대해서는 좀 더 고민할 여지가 있을 것 같습니다.