개발 중에 앱의 테마를 설정하는 기능을 추가 중이였습니다.
recoil을 사용하여 사용자가 원하는 색상을 저장하였고
... 앞에 여러 recoil state..
export const appTheme = atom<Themes>({
key: 'appTheme',
default: '#d54183', // 기본 색상
});
테마를 설정할 때에는 AsyncStorage에 저장하여 앱을 다시 시작하였을 때에도 테마값이 유지되도록 설정하였습니다.
...테마를 설정하는 컴포넌트 안
const pressThemeOkButt = useCallback(() => {
themeList.forEach(async t => {
if (t.checked) { //체크 된 값의 색상을 가져옴
setTheme(t.color); // recoil 저장
await AsyncStorage.setItem('appThemeColor', t.color);
// AsyncStorage에 저장
}
});
pressThemeHideModal();
}, [themeList, pressThemeHideModal, setTheme]);
이는 앱 시작 시 splash screen이 띄어져 있을 때 정보를 불러옵니다.
...Navigation 설정 화면
const getUserData = useCallback(async () => {
try {
const [getUserDataArr, getAppThemeArr] = await AsyncStorage.multiGet([
'user_data',
'appThemeColor',
]);
//앱에 저장되어 있는 유저 정보와 테마 값을 불러옴
const [__, getUserData] = getUserDataArr;
const [_, getAppTheme] = getAppThemeArr;
if (getUserData !== null) {
setUserData(JSON.parse(getUserData));
}
if (getAppTheme !== null) {
setAppTheme(getAppTheme as Themes);
}
} catch (err) {
} finally {
LottieSplashScreen.hide();
}
}, [setUserData, setAppTheme]);
useEffect(() => {
getUserData();
}, [getUserData]);
...여기 까지는 문제 없었습니다.

화면에서 캘린더만 색이 분홍색으로
변경이 된 recoil 값이 적용이 안되어있는 것을 확인할 수 있었습니다.
re-render가 안되었다기에는 위에 글자색과 아래의 그래프 색은 변경이 되어있는 것을 확인 할 수 있었습니다.
해결과정을 찾던 중에 아래의 글을 발견! 👇
https://github.com/wix/react-native-calendars/issues/1884
코드를 아래와 같이 수정하였고
<Calendar
key={theme} // 테마 색 변경시 리렌더링을 위하여
onDayPress={day => {
setSelected(day.dateString);
}}
... 여러값들 설정
/>
react에서 key는 element의 고유값을 줄 때 사용합니다.
ex) map에서 element의 각각의 고유값을 주기 위해서 사용
저도 위와 같이 map에서만 사용할 줄 알았는데
key로 값으로 변경되는 변수를 지정할 경우 값이 변경될 때 마다 전체 트리를 다시 렌더링되어 업데이트가 되는 것을 알게 되었습니다.
참고 자료
위에 자료에서는 강제 리렌더링하는 방법으로 key말고도 여러 방법을 알려주니 한번 보는 것을 추천합니다! 👍
하지만 강제 렌더링 방법이 성능면에서는 좋은 방법은 아닌것 같으니..
값이 자주 변경되는 변수는 key값으로 정하는 것은 안좋을 것 같으며, 이와 같은 방법은 최대한 안쓰는게 좋을 것 같다는 생각이 듭니다.
혹시 이보다 더 좋은 해결 방법을 알고계신다면 알려주세요