원티드 프리온보딩1주차

김용훈·2023년 6월 21일
0

1주차 과제는 사전제출용 과제였던 TodoList를 팀원들끼리 모여서 Best Practice에 대한 이야기를 진행하고 어떤 점을 이유로 채택했는지 근거를 확인하는 과제였다.

1주차 과제
https://github.com/wanted-pre-onboarding-frontend-team4/pre-onboarding-8th-1-4

  1. 폴더구조는
    기능 측면에선 관심사를 auth와 todo로 분리했고,
    폴더를 생성하여 파일을 분리해두었기에 전체 프로젝트의 구조와 기능 파악이 쉽기 때문에 개발 효율성을 향상시킬 수 있습니다.

또한 api 폴더를 따로 생성해주며 컴포넌트 내에서 api기능이 분리되기 때문에 컴포넌트 자체의 전체적인 기능을 직관적으로 확인할 수 있습니다.

src
 ┣ apis
 ┃ ┣ auth.js
 ┃ ┗ todo.js
 ┣ components
 ┃ ┣ common
 ┃ ┃ ┣ Box.style.jsx
 ┃ ┃ ┣ LoginSignUpForm.jsx
 ┃ ┃ ┗ Title.jsx
 ┃ ┗ unit
 ┃ ┃ ┗ todo
 ┃ ┃ ┃ ┣ EmptyList.jsx
 ┃ ┃ ┃ ┣ ListItem.jsx
 ┃ ┃ ┃ ┗ MakeToDo.jsx
 ┣ pages
 ┃ ┣ Login.jsx
 ┃ ┣ NotFound.jsx
 ┃ ┣ SignUp.jsx
 ┃ ┗ ToDo.jsx
 ┣ styles
 ┃ ┣ global-styles.jsx
 ┃ ┗ theme.jsx
 ┣ util
 ┃ ┗ auth.js
 ┣ index.js
 ┗ Router.jsx

2.UI
공통적인 스타일 부분의 코드 중복을 방지하여 재사용성을 높여줍니다. 이를 통해 클린코드가 가능해지며 개발 작업시간을 단축할 수 있습니다.
전체적으로 통일된 UI를 제공하여 사용자 측면에서 안정감있는 서비스를 사용한다고 느낄 수 있습니다.
또한, 전체적으로 공통되는 스타일 중 전체 color등을 theme.jsx 로 따로 관리하여 필요할 때마다 props로 불러와 사용할 수 있는 점에 있어 재사용성이 좋습니다.

const BoxStyle = ({ bgColor, className, children }) => {
  return (
    <TitleContainer color={bgColor} className={className}>
      {children}
    </TitleContainer>
  );
};

3.유효성검사
단순한 메서드만 사용한 것이 아닌 정규표현식을 사용하며 추후에 발생할 에러에 대한 방지 또는 유효성 검사 조건이 추가되더라도 원활히 유지보수가 가능합니다.
사전과제가 요구사항으로는 사용자의 불편함을 초래할 수 있으며 보안상의 문제(비밀번호)가 있을 수 있기 때문에 좀 더 구체적인 조건을 추가할 필요성을 충족시켜줍니다.

//아이디
const emailRegex = /([\w-.!#$%&'+-/=?^_`{|}~]+)@([\w]+.)([a-zA-Z]{2,4}|[0-9]{1,3})$/;

//비밀번호 유효성 검사 ( 숫자, 영문자, 특수문자 조합으로 8자 이상 )
const pwRegex = /^(?=.[a-zA-Z])(?=.[!@#$%^+=-])(?=.*[0-9]).{8,25}$/;

4.인증/인가
로그인/회원가입 과정에서 에러가 발생해도 프로그램이 종료되지 않도록 try~catch문을 사용해 예외처리를 하여 각 에러 발생시 에러 종류에 따라 효율적으로 대응할 수 있습니다.
에러 핸들링 처리가 없다면 회원가입이 되었는지 알 수 없으며 사용자 입장에서는 불필요한 이유로 계속 회원가입을 시도할 수 있습니다.
또한 auth api를 모듈로 만든후 동일 목적의 api instance를 만들어 baseUrl 등 공통 config를 관리하였고, axios interceptor 를 사용해 api 요청전 토큰 여부에 따른 헤더값 세팅으로 유지보수를 쉽도록 하였습니다.

const apiClient = axios.create({
  baseURL: process.env.REACT_APP_BASE_URL,
});

apiClient.interceptors.request.use(
  (config) => {
    const accessToken = localStorage.getItem('token');
    if (accessToken) {
      config.headers.Authorization = Bearer ${accessToken};
    } else {
      delete config.headers.Authorization;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

5.토큰에 따른 리다이렉트
단순히 로그인 → TodoList 로 이동이 아닌 주소창에 바로 todolist로 이동할 url 입력할때를 고려했다는 점이 모든 경우의 수를 생각했다는 점에서 사용자 경험 측면을 굉장히 많이 고려하면서 구현한 로직입니다.
alert창을 구현하는것은 ux측면에서 꼭 필요한 기능입니다. 왜 “/“창으로 넘어가는지 알 수 없다면 사이트의 오류라고 생각할 수 도 있고 사용자가 불필요한 행동을 반복할 수 있기 때문입니다.

useEffect(() => {
    if (!localStorage.getItem('token')) {
      alert('로그인이 필요한 기능입니다.');
      navigate('/');
    }
  }, [navigate]);

6.CRUD 로직 분리
api 모듈화를 통해 반복되는 로직을 분리하기때문에 재사용성이 높아지며, 유지보수가 용이합니다.
직관적인 네이밍을 통해 각 함수의 역할에 대해서 이해하기가 쉬우며 이를 바탕으로 다른 개발자들이 보기에, 즉, 협업하기에 명확하여 코드에 대한 이해도를 향상시킵니다.
axios instance를 생성하고 재사용해서 반복되는 코드를 줄이고자 하였습니다.

import { apiClient } from './auth';

const createTodo = async (body) => {
  const res = await apiClient.post('/todos', body);
  return res;
};

const getTodo = async () => {
  const res = await apiClient.get('/todos');
  return res;
};

const updateTodo = async (body, id) => {
  const res = await apiClient.put(`/todos/${id}`, body);
  return res;
};

const deleteTodo = async (id) => {
  const res = await apiClient.delete(`/todos/${id}`);
  return res;
};

export { createTodo, getTodo, updateTodo, deleteTodo };

7.not found 페이지
ux적으로 사용자가 주소를 잘못 입력했을 때 해당페이지를 보여줌으로서 뒤로가기 혹은 주소 수정을 유도해 해당 페이지를 벗어날 수 있도록 해주는 작업이 필요하다고 생각합니다. 또한, 사용자의 편의성을 위해서 꼭 필요하지만 주니어가 놓치기 쉬운 부분을 잘 캐치해서 구현해주셨습니다.
유효하지않은 경로 접근시 not found 페이지를 보여주는것이 사용자에게 피드백을 주는것이기 때문에 사용자 경험측면에서 좋은방법이 생각합니다. 또한, 404 페이지를 만듦으로써 프로젝트의 완성도를 높일 수 있습니다.

profile
프론트엔드 신입 개발자

0개의 댓글