ziglog

    Search by

    12월 4~5주차 기록

    December 30, 2021 • ☕️ 6 min read

    서러움 가득


    변명같은 건 굉장히 싫어하는 편이다. 그럼에도 4-5주차가 묶인 이유는…


    코로나 집콕일기

    격리기간 동안 기존에 만들던 ‘단짝’ 앱을 잠시 미뤄두고, 같은 형태에 컨텐츠만 다른 앱을 후루룩뚝딱 만들고 있다.

    로그인 로직

    React Navigation 공식문서에서 권장하는 대로, Auth 관련 로직을 React의 Context Provider를 이용하여 hook으로 사용하고 있다.

    앱의 진입점이 될 AppStack 내부에서 isLoggedIn 여부에 따라 보여줄 Navigator를 달리한다. 로그인이 된 유저라면 MainNavigator를, 로그인되지 않은 유저라면 AuthNavigator를 띄운다.

    Copy
    const AppStack = () => {
      const { isLoggedIn } = useAuth();
    
      return (
        <Stack.Navigator screenOptions={{ headerShown: false }}>
          {isLoggedIn ? (
            <Stack.Screen name="Main" component={MainNavigator} />
          ) : (
            <Stack.Screen name="Auth" component={AuthNavigator} />
          )}
        </Stack.Navigator>
      );
    };

    아래와 같이 렌더링된다. 지금은 별다른 로그인 절차없이 버튼만 누르면 넘어갈 수 있게끔 만들었다. AppStack이 Stack Navigator임에도 불구하고 한번 로그인이 된 이상 앱 전역에서 사용하는 isLoggedIn 값이 true기 때문에, MainNavigator의 스크린으로 간 이후에는 다시 로그인 화면으로 돌아올 수 없다.

    중첩된 Navigator와 HoC

    메인 기능은 BottomTabNavigator를 중심으로 화면 전환이 가능한데, 그러는 와중에 각 스크린에서 우측 상단의 설정 버튼 터치 시 설정 화면으로 이동하길 바랐다. (애증의 당근마켓을 많이 참고했다. ㅎㅎ)

    Copy
    const routes = [
      {
        name: "chart",
        // ...
        screen: ChartScreen,
      },
      // ...
    ];
    const Tab = createBottomTabNavigator();
    
    const MainNavigator = () => {
      return (
        <Tab.Navigator
          screenOptions={
            {
              /* ... */
            }
          }
        >
          {routes.map((route) => (
            <Tab.Screen
              key={route.name}
              name={route.title}
              component={route.screen}
              options={
                {
                  /* ... */
                }
              }
            />
          ))}
        </Tab.Navigator>
      );
    };

    createBottomTabNavigator로 기본적인 MainNavigator를 만들고, StackNavigatorHeaderNavigator를 별도로 만들어 설정 관련된 스크린을 포함하도록 했다. 그리고 MainNavigatorScreen에 들어갈 각 컴포넌트들을 withHeaderNavigator로 감싸주었다.

    HoC의 개념만 알고 제대로 사용해본 건 처음이라, 게다가 타이핑까지 해주느라 살짝 애를 먹었다.

    Copy
    const Stack = createStackNavigator();
    
    const HeaderNavigator = ({ component }: Props) => {
      return (
        <Stack.Navigator>
          <Stack.Screen name="Root" component={component} options={{ headerShown: false }} />
          <Stack.Screen
            name="Settings"
            component={SettingsScreen}
            options={{ title: '설정', ...headerOptions }}
          />
        </Stack.Navigator>
      );
    };
    
    const withHeaderNavigator =
      <P extends object>(Component: React.ComponentType<P>) =>
      () =>
        <HeaderNavigator component={Component} />;
    const ChartScreen = () => {
      return (
        // ...
      )
    }
    
    export default withHeaderNavigator(ChartScreen);

    아래와 같이 잘 동작한다!

    DatePicker

    처음에는 @react-native-community/datetimepicker를 선택했었다. 다운로드 수도 가장 많고, expo에서 공식 지원하는 문서가 있었기 때문이다.

    그런데 해당 라이브러리는 날짜가 보이는 형식을 커스터마이징할 수가 없었다. 그리고 버튼을 눌렀을 때 하단 모달 형태로 DatePicker만 띄우길 원했는데, 한번 네이티브한 날짜 표기가 뜨고 그 이후에 다시 날짜를 눌러야만 DatePicker가 나와서 맘에 들지 않았다.

    그래서 선택한 것은 react-native-modal-datetime-picker다. 다운로드 수도 꽤 되고, 내부적으로 @react-native-modal-datetime-picker를 사용한다고 하니 단순히 UI적으로만 간편하게 도움을 받을 수 있을 것 같았다.

    Chart library

    차트 라이브러리 선택이 정말 골칫덩어리였다. 우선 고려사항이었던 라이브러리들은 다음과 같다.

    • react-native-svg-charts - 커스터마이징을 자유롭게 할 수 있지만, 너무나 날것이다. 빠르게 만들어 배포하기에는 적합하지 않다.
    • react-native-charts-wrapper - 용량이 매우 커서 별로다.

    그래서 가장 처음에 선택했던 react-native-chart-kits를 그대로 쓰기로 했는데, 커스터마이징이 정말 어렵다. 깃헙에 이슈도 엄청 많고, 그냥 돌아버린다. 그래도 차악이라 어쩔 수 없이 사용한다. 지금만 해도 bar의 backgroundColor 커스텀이나 topValue의 margin 설정, 숫자 포맷팅 등을 전혀 할 수 없다.

    그래도 일단 그냥 두어야지 🤦‍♀️

    04

    TextInputonChangeText

    React Native의 TextInput에는 onChangeonChangeText 속성 두 가지가 있다. 뭔지 몰라 각각의 타입 시그니처를 살펴봤다.

    Copy
    onChange?: ((e: NativeSyntheticEvent<TextInputChangeEventData>) => void) | undefined;
    
    onChangeText?: ((text: string) => void) | undefined;

    완전 좋다! 더 이상 구질구질하게 event.target.value와 같은 코드를 작성하지 않아도 된다. 아래처럼 바로 setState를 넘겨줄 수 있는 것이다!

    Copy
    const SignInScreen = () => {
      const [name, setName] = useState("");
    
      return (
        <TextInput
          value={name}
          onChangeText={setName}
          placeholder="이름을 입력해주세요"
        />
      );
    };

    왜 이런거 React에는 안 만들어줘 🤯


    기타

    벨로그의 프론트엔드 작가

    Ref https://velog.io/@teo

    주니어를 넘어서, 성장하는 개발자의 길

    • 위키 형식으로 블로그 관리하기
    • 주어진 기회를 놓치지 않고, 먼저 나서서 일하기
    • 코드리뷰하기
    • 테스트코드 작성하기
    • 일지에서 히스토리로, 히스토리에서 문서로
    • 짝코딩으로 스스로의 문제 파악하기
    • 내가 먼저 좋은 친구 되기

    Ref https://www.inflearn.com/pages/weekly-inflearn-38-20211228

    플래시의 죽음에서 배우는 위기를 기회로 만드는 방법

    좋은 개발자는 특정 개발 언어를 깊게 파서 마스터하는 개발자가 아니라, 시장과 사용자가 요구하는 기술에 빠르게 대응할 수 있는 개발자다. 끊임없이 공부하고, 시대가 변하더라도 변하지 않는 내공에 집중하자. 개발의 목표는 개발 언어 공부 자체가 아니라, 그 결과물이다.

    Ref https://www.youtube.com/watch?v=0WUXSPEp-cc


    마무리

    코로나에 걸렸다. 지난주는 내내 몸도 아팠고, 정신적으로도 스트레스가 너무 컸다. 취업하자마자 아무것도 못하고 코로나라니. 격리기간에 크리스마스도 연말도 다 껴버리다니. 연속으로 많은 회사들을 떨어졌을 때보다도 더 힘들었다. 그리고 백신을 굉장히 불신하게 됐다. 맞으면 뭐하나. 가족 전부 다 걸리고 약을 다시 타 받아 먹을 정도로 증상도 꽤나 심했는걸. 이제 돌이킬 수 없는 폐를 갖게 됐다는 사실이 끔찍하다. 백신패스 때문에 부스터샷은 맞아야겠지만, 그냥 무능한 정부가 원망스럽다.

    태어나서 가장 긴 기간 동안 외출하지 못한 채 아픈 상태로 혼자 지내면서, 끝없이 찾아오는 불행한 생각을 덜어내려고 앱을 만들기 시작했다. 격리되어본 사람만 알 수 있는 느낌을 가득 담고 있다.

    그래도 주위 좋은 사람들 덕에 조금씩 이겨내고 있다. 애써 생각을 바꿔보려고 한다. 계속 불행하게만 생각하면 나아질 게 하나도 없는 건 맞다. 무척 속상한 건 맞지만, 인생이 무너질 정도의 재산적 피해나 삶을 송두리째 바꿔버릴 상실감, 그런 게 아니잖아. 분명 나는 젊고, 아직 할 수 있는 것들이 많이 있다.


    Relative Posts:

    1월 첫주차 기록

    January 8, 2022

    12월 3주차 기록

    December 19, 2021

    zigsong

    지그의 개발 블로그

    RotateLinkImg-iconRotateLinkImg-iconRotateLinkImg-icon