[TIL] 2023. 1. 2.

suno·2023년 1월 2일
post-thumbnail

✅ 오늘 한 일


  1. React Native with Firebase
    React Native로 작성한 Todo List 앱에 Firebase를 연결했다.
    Firebase의 Realtime Database를 사용해봤다.

  2. Redux Thunk 복습
    아직 Redux의 흐름과 미들웨어에 대해 익숙하지 않다.
    React Native에서 Thunk로 카운터 만들기부터 다시 해봤다.

  3. 선발대 강의
    라이브 코딩으로 내가 만든 Todo List를 리팩토링 했다.
    굉장히 낯설었지만 하나하나 던져주는 피드백이 도움이 많이 되었다.
    특히 내가 모르는 라이브러리나 익스텐션을 알 수 있어 좋았다.

  4. 도전목록 하나 추가
    선발대 팀원분이 알려주셔서 원티드 프리온보딩 프로그램을 신청했다.
    마침 이번달 주제가 React Query라서 엄청엄청 유익할 것 같다. ❣️


🏃‍♀️ 학습할 것

  • Redux Thunk
    React Native에서 서버 통신을 할 때 사용해 볼 것.
    그런데 서버 통신과 로컬 state 관리를 어떻게 나누어야 할지 모르겠다.
    어차피 CRUD를 서버에다가 하는데 전역 state로 관리해야 하는 이유가 뭘까? 튜터님에게 질문해야지!

  • React Life Cycle
    클래스형 컴포넌트와 라이프 사이클을 공부할 것.
    이걸 알아야 리액트 렌더링에 대해 완벽하게 이해할 수 있을 것 같다.

  • 놓친 특강 듣기
    CPU, React Query 등등,, 너무 많다 🥲


👾 구현할 것

  • Custom Hook
    React Native - Todo List를 Custom Hook으로 리팩토링 하기

💡 오늘 배운 것

Redux Toolkit - nanoid

Other Exports | Redux Toolkit
non-cryptographically-secure random ID string 을 반환해주는 라이브러리이다.
id를 만들기 위해 uuid 라이브러리를 따로 설치할 필요 없이 redux toolkit에 내장되어 있는 nanoid를 사용하면 된다.

Custom Hook

AddForm 리팩토링

custom hook으로 내부 로직을 분리하면, component 코드가 매우 깔끔해진다.
코드가 길어질수록 component에서는 렌더링 요소만 관리하고 로직은 custom hook에서 관리하는 것이 훨씬 편할 듯 하다.

  • 변경 전

    // components/AddForm.jsx
    
    import React, { useState } from 'react';
    import { useMutation } from '@tanstack/react-query';
    import { queryClient } from '../../App';
    import Button from '../common/Button/Button';
    import * as styled from './AddForm.style';
    import axios from 'axios';
    import { SERVER_URL } from '../../common/axios/constant';
    
    export default function AddForm() {
      const [todoValue, setTodoValue] = useState('');
      const [visible, setVisible] = useState(false);
    
      const mutationAdd = useMutation({
        mutationFn: async (newTodo) => {
          await axios.post(`${SERVER_URL}/todos`, newTodo);
        },
        onSuccess: () => {
          queryClient.invalidateQueries('todos');
        },
      });
    
      // input 값이 바뀔 때 todoValue 값을 업데이트
      const handleChange = (e) => {
        setTodoValue(e.target.value);
      };
    
      // form이 submit되면 실행되는 함수. todo를 추가함
      const handleSubmit = (event) => {
        event.preventDefault();
    
        const todo = todoValue.trim(); // todo 앞뒤 공백을 제거
        if (!todo) {
          // todo 입력값이 없으면 초기화 후 리턴
          setTodoValue('');
          setVisible(true); // 경고문구 표시
          return;
        }
    
        // DB에 todo 추가
        mutationAdd.mutate({ isDone: false, todo });
        setVisible(false); // 경고문구 숨김
        setTodoValue('');
      };
    
      return (
        <styled.TodoFormContainer>
          <styled.TodoForm onSubmit={handleSubmit}>
            <styled.TodoLabel htmlFor='new-todo'>To Do </styled.TodoLabel>
            <styled.TodoInput
              type='text'
              id='new-todo'
              name='new-todo'
              onChange={handleChange}
              autoFocus={true}
              value={todoValue}
            />
            <styled.TodoInputErrorMessage visible={visible}>
              내용을 입력하세요.
            </styled.TodoInputErrorMessage>
            <Button value='추가' />
          </styled.TodoForm>
        </styled.TodoFormContainer>
      );
    }
  • 변경 후

    // components/AddForm.jsx
    
    import Button from '../common/Button/Button';
    import * as styled from './AddForm.style';
    import { useInput } from '../../hooks/useInput';
    
    export default function AddForm() {
      const { visible, handleSubmit, todoValue, handleChange } = useInput();
    
      return (
        <styled.TodoFormContainer>
          <styled.TodoForm onSubmit={handleSubmit}>
            <styled.TodoLabel htmlFor='new-todo'>To Do </styled.TodoLabel>
            <styled.TodoInput
              type='text'
              id='new-todo'
              name='new-todo'
              onChange={handleChange}
              autoFocus={true}
              value={todoValue}
            />
            <styled.TodoInputErrorMessage visible={visible}>
              내용을 입력하세요.
            </styled.TodoInputErrorMessage>
            <Button value='추가' />
          </styled.TodoForm>
        </styled.TodoFormContainer>
      );
    }
    // hooks/useForm.jsx
    
    import { useState } from 'react';
    import { queryClient } from '../App';
    import { useMutation } from '@tanstack/react-query';
    import axios from 'axios';
    import { SERVER_URL } from '../common/axios/constant';
    
    export const useForm = () => {
      const [todoValue, setTodoValue] = useState('');
      const [visible, setVisible] = useState(false);
    
      // input 값이 바뀔 때 todoValue 값을 업데이트
      const handleChange = (e) => {
        setTodoValue(e.target.value);
      };
    
      const mutationAdd = useMutation({
        mutationFn: async (newTodo) => {
          await axios.post(`${SERVER_URL}/todos`, newTodo);
        },
        onSuccess: () => {
          queryClient.invalidateQueries('todos');
        },
      });
    
      const handleSubmit = (event) => {
        event.preventDefault();
    
        const todo = todoValue.trim(); // todo 앞뒤 공백을 제거
        if (!todo) {
          // todo 입력값이 없으면 초기화 후 리턴
          setTodoValue('');
          setVisible(true); // 경고문구 표시
          return;
        }
    
        // DB에 todo 추가
        mutationAdd.mutate({ isDone: false, todo });
        setVisible(false); // 경고문구 숨김
        setTodoValue('');
      };
    
      return { visible, todoValue, handleChange, handleSubmit };
    };

💭 오늘의 잡담

  • 1월 1일에 세운 2023년 목표 키워드는 관계 였다. 그런데 신기하게도 첫주부터 목표에 가까워지고 있는 것 같다.
    정말 남는 건 사람(+허리/어깨 통증ㅋ) 뿐이다.. 🥲
    캠프에서 만난 사람들은 물론이고, 공부하는 나를 이해하고 배려해주는 주변인들에게도 잊지 않고 잘해야겠다.
  • 작년에는 거의 반년을 집에서 보냈는데, 올해에는 오프라인(현생)에서 다양한 경험을 해보고싶다.
  • 캠프 중반을 넘어 느슨해진 마음에 새로운 자극을 받게 되어 너무 좋다.❣️
profile
Software Engineer 🍊

0개의 댓글