App 내에서 DarkMode, LightMode를 설정할 수 있게 하는 방법을 공유합니다
light 모드와 dark 모드에 사용할 테마를 분리해서 만듭니다.
styled-components는 이 theme 객체를 통째로 바꿔 테마를 변경합니다.
export const light = {
color: {
mainBg: "#ffffff",
},
};
export const dark = {
color: {
mainBg: "#000000",
},
};
import { ThemeProvider } from "styled-components";
import { light, dark } from "@src/Theme";
...
const App = () => {
return (
//...
//일단 Theme를 light로 잠시 고정해둡니다. 변경하는 방법은 뒤쪽에서 설명합니다.
<ThemeProvider theme={light}>
<NavigationContainer>
<HomeStack />
</NavigationContainer>
</ThemeProvider>
//...
);
};
ThemeProvider에서 설정한 Theme은 별다른 설정없이 StyledComponent에서 인자로 사용할 수 있습니다.
import styled from "styled-components/native";
...
// 첫번째 방법: props로 가져오기
const MyComp = styled.View`
background: ${(props) => props.theme.color.mainBg};
width: 100%;
height: 100%;
`;
// 두번째 방법: 비구조화 할당으로 가져오기
const MyComp2 = styled.View`
background: ${({ theme }) => theme.color.mainBg};
width: 100%;
height: 100%;
`;
여기까지 하면 light 테마가 적용된 것을 확인할 수 있습니다.
하지만 아직 테마 변경이 불가능하죠. 그래서 테마를 변경하는 기능을 추가하려고 합니다.
이 객체는 오직 테마 변경만을 위해 존재합니다.
ReactNative 최신버전에서는 react-native-appearance 라이브러리는 deprecated 되었고 대신 Appearance가 통째로 react-native 내부에 포함되었습니다.
expo는 SDK 43부터 react-native-appearance를 지원하지 않습니다.
expo를 사용하는 경우, app.json에 다음 내용이 추가되어야 합니다.
추가하지 않을 경우, 항상 light 만 사용하게 됩니다.
{
"expo": {
"userInterfaceStyle": "automatic",
"ios": {
"userInterfaceStyle": "automatic"
},
"android": {
"userInterfaceStyle": "automatic"
}
}
}
//참고: https://github.com/facebook/react-native/issues/31806
사용할 수 있는 방법이 2개가 있습니다.
App.tsx
의 ThemeProvider
에서 사용하면 끝입니다. import { useColorScheme } from "react-native";
import { light, dark } from "@src/Theme";
const App = () => {
return (
//...
<ThemeProvider theme={useColorScheme() === "light" ? light : dark}>
<NavigationContainer>
<HomeStack />
</NavigationContainer>
</ThemeProvider>
//...
);
};
import { Appearance } from "react-native";
const App = () => {
const [appTheme, setAppTheme] = useState(light);
useEffect(() => {
Appearance.addChangeListener(({ colorScheme }) => {
setAppTheme(Appearance.getColorScheme() === "dark" ? dark : light);
});
return () => {};
}, []);
return (
//...
<ThemeProvider theme={appTheme}>
<NavigationContainer>
<HomeStack />
</NavigationContainer>
</ThemeProvider>
//...
);
};
좋은 자료 감사합니다.