1. 폴더&파일명

    1. 폴더명: kebab case를 사용한다. (url, 파일 경로에 어울림) 예: components, user-profile, login-page
    2. 컴포넌트: PascalCase를 사용한다. (react 컴포넌트는 대문자로 시작하기 때문에 어울림) 예: UserProfile.tsx, LoginPage.tsx
    3. 기타 파일명(utility 함수, API 호출 관련 파일 등): camelCase를 사용한다. (함수, 모듈 느낌에 부합하고 명확하게 구분 가능) 예: apiService.ts, userUtils.ts, fetchData.ts
  2. 주석

    1. 만약 해야할 사항이 있다면 // TODO: 주석으로 해야 할 내용을 표시한다.
    2. 어떤 역할을 하는 지 개발자들끼리 이해가 필요한 경우라면 주석으로 작성한다.
  3. 확장자 (성능 개선, 일관성 유지)

    1. ui와 관련된 파일(atom, molecules, feature, components)의 확장자는 .tsx로 정한다. → 가상DOM이 있는 파일
    2. 데이터 페칭, 로직을 작성하는 파일의 확장자는 .ts 로 정한다.
  4. 변수/함수명

    1. 변수/함수명은 이해할 수 있을 정도로 충분히 고민해보자. ex) isLoading (x), isUserDataLoading (o)

    2. 대부분의 경우 카멜 케이스를 사용한다.

      // Bad
      const is_snake_case = 'Bad'
      
      // Good
      const camelCase = 'Good'
      
    3. 상수는 영문 대문자 스네이크 표기법을 사용한다.

    1. class 생성자 / 생성자 함수는 대문자 카멜 케이스를 사용한다.

      // class 생성자
      class ClassName {}
      
      // 생성자 함수
      function Person() {}
      
    2. URL, HTML 같은 범용적인 대문자 약어는 대문자 그대로 사용한다.

      const parseHTML = () => {}
      const parseXML = () => {}
      
    3. 이벤트 핸들러명

      1. on으로 시작하도록 한다.
      // Good
      const onClick
      const onSubmit
      
      // Bad
      const clickHandler
      const handleClick
      const onClickHandler
      
    4. 들여쓰기는 무조건 tab 키로 2칸 띄운다. (prettier에 설정돼있음)

    5. 문장의 끝은 세미콜론으로 끝나도록 한다. (prettier에 설정돼있음)

    6. 전역 변수는 되도록 사용하지 않는다.

    7. 변수 선언 시, var는 절대 사용하지 않는다. 되도록 const를 사용하되, 부득이한 경우 let을 사용한다.

    8. 외부 모듈과 내부 모듈을 구분지어 import 한다**. (외부 모듈부터 정리)**

    import { useState, useEffect } from 'react';
    import { useNavigate } from 'react-router-dom';
    import axios from 'axios';
    
    import pluginFactory from '../../factories/pluginFactory';
    import predicate from '../../helpers/predicate';
    import raphaelRenderUtil from '../../plugins/raphaelRenderUtil';
    
    1. 함수 표현식 대신에 화살표 함수를 사용한다. 화살표 함수는 별도의 this 바인딩 없이 상위 컨텍스트에 바인딩 되기 때문에 함수 표현식보다 혼란이 적으며, 덜 장황하고 추론이 쉽다.
    // Bad
    [1, 2, 3].map(function(x) {
    	const y = x + 1;
    	return x + y;
    });
    
    // Good
    [1, 2, 3].map((x) => {
    	const y = x + 1;
    	return x + y;
    });
    
    1. 배열과 객체는 리터럴로 선언한다.
    // Bad
    const emptyArr = new Array();
    const arr = new Array(1, 2, 3, 4, 5);
    
    // Bad - 객체 생성자 사용
    const emptyObj = new Object();
    const obj = new Object();
    
    // Good
    const emptyArr = [];
    const arr = [1, 2, 3, 4, 5];
    
    // Good
    const emptyObj = {};
    const obj = {
      pro1: 'val1', 
      pro2: 'val2'
    };
    
    1. 객체의 프로퍼티에 접근할 땐 Destructuring을 사용한다.
    // Bad
    function getFullName(user) {
      const firstName = user.firstName;
      const lastName = user.lastName;
    
      return `${firstName} ${lastName}`;
    }
    
    // Bad
    const first = arr[0];
    const second = arr[1];
    
    // Good
    function getFullName(obj) {
      const {firstName, lastName} = obj;
    
      return `${firstName} ${lastName}`;
    }
    
    // Good
    const [first, second] = arr;
    
    // Good
    function getFullName({firstName, lastName}) {
      return `${firstName} ${lastName}`;
    }
    
    1. 그러나 새로운 이름으로 변수에 할당하고 싶을 때는 꼭 Destructuring을 사용하지 않아도 된다.
    // Good
    const changeFirstName = user.firstName;
    
    // Good
    const {firstName: changeFirstName} = user;
    
    1. 변수 등을 조합해 문자열을 생성하는 경우, 템플릿 문자열을 이용한다.
    // Bad
    function sayHi(name) {
      return 'How are you, ' + name + '?';
    }
    
    // Bad
    function sayHi(name) {
      return ['How are you, ', name, '?'].join();
    }
    
    // Bad - 일반적인 경우, 홑따옴표를 사용
    function sayHi(name) {
      return `How are you name?`;
    }
    
    // Good
    function sayHi(name) {
      return `How are you, ${name}?`;
    }
    
    1. 비교 시에 ===!== 연산자만 사용한다.