[Debug] react-native-calendars 사용시 동적 색상 적용 에러

Burkey·2023년 12월 14일

Debug

목록 보기
5/6

개발 중인 기능

개발 중에 앱의 테마를 설정하는 기능을 추가 중이였습니다.
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값으로 정하는 것은 안좋을 것 같으며, 이와 같은 방법은 최대한 안쓰는게 좋을 것 같다는 생각이 듭니다.
혹시 이보다 더 좋은 해결 방법을 알고계신다면 알려주세요

profile
스탯 올리는 중

0개의 댓글