// ThemeContext.jsx
import React from "react";
const ThemeContext = React.createContext();
// 초기값 별도 설정 안하고 provider로 설정 예정
ThemeContext.displayName = 'ThemeContext';
// 개발자 도구 확인용
export default ThemeContext;
// MainContent.jsx
import { useContext } from "react";
// useContext hook 사용
import ThemeContext from "./ThemeContext";
function MainContent(props) { // 메인컨텐츠 컴포넌트
// ThemeContext로 부터 설정된 테마 값을 받아와 실제 화면에 컨텐츠 렌더링
const { theme, toggleTheme } = useContext(ThemeContext);
return(
<div
style={{
width: '100vw',
height: '100vh',
padding: '1.5rem',
backgroundColor: theme == 'light' ? 'white' : 'black',
color: theme == 'light' ? 'black' : 'white',
}}
>
<p>안녕하세요, 테마 변경이 가능한 웹사이트 입니다.</p>
<button onClick={toggleTheme}>테마 변경</button>
// ThemeContext의 값 변경
</div>
);
}
export default MainContent;
// DarkOrWhite.jsx
import { useState, useCallback } from "react";
import ThemeContext from "./ThemeContext";
import MainContent from "./MainContent";
function DarkOrLight(props) {
const [theme, setTheme] = useState('light');
const toggleTheme = useCallback(() => {
if (theme == 'light'){
setTheme('dark');
}else if (theme == 'dark'){
setTheme('light');
}
}, [theme]);
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
// Provider로 감싸 하위 컴포넌트가 값을 사용 할 수 있도록 해준다.
<MainContent />
</ThemeContext.Provider>
)
}
export default DarkOrLight;
변경 전
변경 후
위에 사용된 useCallback이 잘 기억이 나지 않는다.
useCallback()은 함수를 메모이제이션(memoization)하기 위해서 사용되는 hook 함수.
첫번째 인자로 넘어온 함수를, 두번째 인자로 넘어온 배열 내의 값이 변경될 때까지 저장해놓고 재사용할 수 있게 해준다.
const add = () => a + b;
예를 들어, 컴포넌트 함수 안에 함수가 선언이 되어 있다면 이 함수는 해당 컴포넌트가 렌더링될 때 마다 새로운 함수가 생성되고, 자원 낭비로 이어진다.
const add = () => a + b;
하지만 useCallback()을 사용하면, 해당 컴포넌트가 렌더링 되더라도 그 함수가 의존하는 값들이 바뀌지 않는 한 기존 함수를 반환한다.
즉, a나 b의 값이 바뀌지 않으면 재사용을 하고, 값이 바뀌면 그 때 새로운 함수가 생성되어 add변수에 할당된다.