Skip to content

πŸ“– ν”„λ‘œμ νŠΈ 폴더ꡬ쑰 및 μ„€λͺ…

μ‹ μ€μˆ˜ edited this page Aug 31, 2023 · 1 revision

1. ν”„λ‘œμ νŠΈ 폴더ꡬ쑰

πŸ“· focal
β”œβ”€ .github
β”‚  └─ PULL_REQUEST_TEMPLATE.md ────── βš™οΈΒ PR ν…œν”Œλ¦Ώ
│─ .gitignore
│─ .prettierrc   ──────────────────── βš™οΈ prettier μ„€μ • 파일
│─ .eslintrc     ──────────────────── βš™οΈ eslint μ„€μ • 파일
β”œβ”€ πŸ“‚Β public
β”‚  β”œβ”€ favicon.ico
β”‚  └─ index.html
└─ πŸ“‚ src
  β”œβ”€ πŸ“‚ api     ─────────────────────  Axios μΈμŠ€ν„΄μŠ€ 및 API κ΄€λ ¨ λͺ¨λ“ˆ ν•¨μˆ˜
  β”œβ”€ πŸ“‚ assets  ─────────────────────  μ•„μ΄μ½˜, 이미지 λ“± 정적 λ¦¬μ†ŒμŠ€
  β”œβ”€ πŸ“‚ states ─────────────────────── 리코일 κ΄€λ ¨ 폴더
  β”œβ”€ πŸ“‚ components
  β”‚  β”œβ”€ πŸ“‚ common ─────────────────── 곡톡 μ»΄ν¬λ„ŒνŠΈ
  β”‚  β”œβ”€ πŸ“‚ Chat ───────────────────── route pathκ°€ chat인 νŽ˜μ΄μ§€μ—μ„œ μ‚¬μš©λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ 
  β”‚  β”œβ”€ πŸ“‚ Follow ─────────────────── route pathκ°€ follow인 νŽ˜μ΄μ§€μ—μ„œ μ‚¬μš©λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ
  β”‚  β”œβ”€ πŸ“‚ Login ──────────────────── route pathκ°€ login인 νŽ˜μ΄μ§€μ—μ„œ μ‚¬μš©λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ
  β”‚  β”œβ”€ πŸ“‚ Post ───────────────────── route pathκ°€ post인 νŽ˜μ΄μ§€μ—μ„œ μ‚¬μš©λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ
  β”‚  β”œβ”€ πŸ“‚ Product ────────────────── route pathκ°€ product인 νŽ˜μ΄μ§€μ—μ„œ μ‚¬μš©λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ
  β”‚  β”œβ”€ πŸ“‚ Profile   ──────────────── route pathκ°€ profile인 νŽ˜μ΄μ§€μ—μ„œ μ‚¬μš©λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ
  β”‚  β”œβ”€ πŸ“‚ Search ─────────────────── route pathκ°€ search인 νŽ˜μ΄μ§€μ—μ„œ μ‚¬μš©λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ
  β”‚  └─ πŸ“‚ Signup ─────────────────── route pathκ°€ signup인 νŽ˜μ΄μ§€μ—μ„œ μ‚¬μš©λ˜λŠ” μ»΄ν¬λ„ŒνŠΈ
  β”œβ”€ πŸ“‚ layouts   ────────────────────  κ³΅ν†΅μœΌλ‘œ μ‚¬μš©λ˜λŠ” λ ˆμ΄μ•„μ›ƒ
  β”œβ”€ πŸ“‚ pages   ───────────────────── λΌμš°νŒ…μ΄ 적용된 νŽ˜μ΄μ§€λ“€μ„ λͺ¨μ•„놓은 폴더
  β”œβ”€ πŸ“‚ routes ───────────────────── λΌμš°νŠΈμ™€ κ΄€λ ¨λœ νŒŒμΌλ“€μ„ λͺ¨μ•„놓은 폴더
  β”‚  β”œβ”€ PrivateRoute.js
  β”‚  β”œβ”€ PublicRoute.js
  β”‚  └─ Router.js
	β”œβ”€ πŸ“‚ states ──────────────────── Recoil κ΄€λ ¨ 폴더
  β”œβ”€ πŸ“‚ hooks ─────────────────────── μ»€μŠ€ν…€ ν›… 폴더
  β”‚  β”œβ”€ useDebounce.js
  β”‚  β”œβ”€ useHandleResizeHeight.js
  β”‚  β”œβ”€ useModal.js
  β”‚  └─ useScrollBottom.js
  β”œβ”€ πŸ“‚ constants   ───────────────── μƒμˆ˜
  β”œβ”€ πŸ“‚ utils    ──────────────────── κ³΅ν†΅μœΌλ‘œ μ‚¬μš©λ˜λŠ” μœ ν‹Έ ν•¨μˆ˜
  β”‚  β”œβ”€ converTime.js
  β”‚  β”œβ”€ getDate.js
  β”‚  β”œβ”€ getProperImagSrc.js
	β”‚  └─ handleImageError.js
  β”œβ”€ App.js
  β”œβ”€ index.js
  └─ GlobaledStyled.js

2. μ „μ—­μƒνƒœκ΄€λ¦¬ 라이브러리둜 Recoil을 μ„ νƒν•œ 이유

  • μ €ν¬λŠ” μ „μ—­μƒνƒœκ΄€λ¦¬ 라이브러리둜 Redux와 Recoil 쀑 μ„ νƒν•˜κ³ μž ν•˜μ˜€μŠ΅λ‹ˆλ‹€.
  • λ¨Όμ € ReduxλŠ” μƒνƒœ, μ•‘μ…˜, λ¦¬λ“€μ„œλ‘œ κ΅¬μ„±λ˜λ©° μ—„κ²©ν•œ νŒ¨ν„΄μ„ λ”°λ₯΄λŠ” μƒνƒœκ΄€λ¦¬ λΌμ΄λΈŒλŸ¬λ¦¬μž…λ‹ˆλ‹€. λŒ€κ·œλͺ¨ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ λ³΅μž‘ν•œ μƒνƒœ 관리에 μ ν•©ν•˜λ©°, λ§Žμ€ μƒνƒœ λ³€ν™”κ°€ ν•„μš”ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.
  • ν•˜μ§€λ§Œ 저희 ν”„λ‘œμ νŠΈλŠ” 비ꡐ적 μ†Œκ·œλͺ¨ ν”„λ‘œμ νŠΈμ—¬μ„œ λ³΅μž‘ν•œ μƒνƒœκ΄€λ¦¬κ°€ ν•„μš”ν•˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ ReduxλŠ” λ°°μ œμ‹œμΌ°μŠ΅λ‹ˆλ‹€.
  • 반면 Recoil은 μƒλŒ€μ μœΌλ‘œ κ°„λ‹¨ν•˜κ³ , React 문법 μΉœν™”μ μΈ λΌμ΄λΈŒλŸ¬λ¦¬μž…λ‹ˆλ‹€. μ „μ—­μƒνƒœλ₯Ό μ†μ‰½κ²Œ κ΄€λ¦¬ν•˜μžλŠ”κ²Œ 주된 λͺ©ν‘œμ˜€κΈ°λ•Œλ¬Έμ— μ—¬λŸ¬κΈ°λŠ₯을 ν•„μš”λ‘œ ν•˜μ§„ μ•Šμ•˜κ³ , κ·Έ λ•Œλ¬Έμ— 비ꡐ적 κ°„λ‹¨ν•œ Recoil을 μ„ νƒν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

3. λ°˜λ³΅λ˜λŠ” μ½”λ“œλ₯Ό μ œκ±°μ™€ μ½”λ“œ νš¨μœ¨μ„ μœ„ν•΄ Axios Instance μ‚¬μš©

1) Axios Instanceλ₯Ό λ§Œλ“€μ–΄ μ“°κΈ°μ „

const token = localStorage.getItem('token')
await axios({
    url: `${process.env.REACT_APP_BASE_URL}post/${post_id}`,
    method: 'PUT',
    data: {
      post: {
        content,
        image: image.join(),
      },
    },
    headers: {
      Authorization: `Bearer ${token}`,
  },
});
  • api μš”μ²­μ„ ν•  λ•Œλ§ˆλ‹€ ν•΄λ‹Ήμ½”λ“œλ₯Ό 일일이 λ‹€ μ¨μ•Όν•΄μ„œ μ½”λ“œκ°€ 반볡되고, κΈΈμ–΄μ§„λ‹€λŠ” 단점이 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

2) Axios Instance와 Interceptor μ‚¬μš©

  • ./api/instance/authInstance.js

    import axios from 'axios';
    
    const authAPI = (url, options) => {
      return axios.create({ baseURL: url, ...options });
    };
    
    const authInstance = authAPI(process.env.REACT_APP_BASE_URL);
    
    authInstance.interceptors.request.use(
      (config) => {
        const token = localStorage.getItem('token');
        config.headers['Content-Type'] = 'application/json';
        config.headers['Access-Control-Allow-origin'] = '*';
        config.headers['Authorization'] = `Bearer ${token}`;
    
        return config;
      },
      (error) => {
        console.log(error);
        return Promise.reject(error);
      },
    );
    
    export default authInstance;
    • Axios interceptorλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ μ²˜λ¦¬ν•˜κΈ° 전에 AxiosλΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ μˆ˜ν–‰ν•œ HTTP μš”μ²­ λ˜λŠ” 응닡을 κ°€λ‘œμ±„κ³  μˆ˜μ •ν•˜λŠ” 데 μ‚¬μš©ν•  수 μžˆλŠ” κΈ°λŠ₯μž…λ‹ˆλ‹€. μš”μ²­μ— 인증 헀더 μΆ”κ°€, 였λ₯˜ 처리 λ˜λŠ” μš”μ²­ 및 응닡 λ‘œκΉ…κ³Ό 같은 λ‹€μ–‘ν•œ μš©λ„λ‘œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ‹€μ œ μ‚¬μš©μ‹œ

    await authInstance.put(`/post/${post_id}`, {
      post: {
        content,
        image: image.join(),
      },
    });
    • baseUrl, headers, timeout 등을 μ—¬λŸ¬ κ³³μ—μ„œ λ°˜λ³΅ν•΄μ„œ μž‘μ„±ν•  ν•„μš”κ°€ μ—†μ–΄ μ½”λ“œ νš¨μœ¨μ„ 높일 수 있게 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.