๐ŸŒ React์—์„œ ๋™์  ๋‹ค๊ตญ์–ด ์ง€์› ์‹œ์Šคํ…œ ๊ตฌํ˜„ํ•˜๊ธฐ

junhyung kwonยท4์ผ ์ „
0

๐Ÿ“Š ์šด์˜ ๊ฒฐ๊ณผ

  • ๋ฒˆ์—ญ ํŒŒ์ผ ํ˜„ํ™ฉ

    • ํ•œ๊ตญ์–ด: 1,162๊ฐœ ํ‚ค (๊ธฐ์ค€)
    • ์˜์–ด: 1,162๊ฐœ ํ‚ค (100% ์™„๋ฃŒ)
    • ์ผ๋ณธ์–ด: 1,162๊ฐœ ํ‚ค (100% ์™„๋ฃŒ)
    • ๋Œ€๋งŒ์–ด: 1,162๊ฐœ ํ‚ค (100% ์™„๋ฃŒ)
  • ์„ฑ๋Šฅ ์ง€ํ‘œ

    • ์ดˆ๊ธฐ ๋กœ๋”ฉ ์‹œ๊ฐ„: ํ‰๊ท  200ms
    • ์–ธ์–ด ์ „ํ™˜ ์‹œ๊ฐ„: ํ‰๊ท  50ms
    • ๋ฒˆ๋“ค ํฌ๊ธฐ ์ ˆ์•ฝ: ์•ฝ 150KB (๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋Œ€๋น„)

๐Ÿšจ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…

์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋“ค

  1. ๋ฒˆ์—ญ ํ‚ค๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ
// ๋ฌธ์ œ: ์ค‘์ฒฉ๋œ ํ‚ค์—์„œ undefined ์ ‘๊ทผ
const t = (key) => {
  // โŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์—๋Ÿฌ ๋ฐœ์ƒ
  return translations.header.login; 
  
  // โœ… ์•ˆ์ „ํ•œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•
  return translations?.header?.login || key;
};
  1. ์–ธ์–ด ์„ค์ •์ด ์ƒˆ๋กœ๊ณ ์นจ ํ›„ ์ดˆ๊ธฐํ™”๋˜๋Š” ๋ฌธ์ œ
// ํ•ด๊ฒฐ: localStorage ์ฒดํฌ ๋กœ์ง ๊ฐœ์„ 
useEffect(() => {
  const savedLanguage = localStorage.getItem('selectedLanguage');
  if (savedLanguage && availableLanguages.includes(savedLanguage)) {
    changeLanguage(savedLanguage);
  }
}, []);

โšก ์„ฑ๋Šฅ ์ตœ์ ํ™”

1. ์ง€์—ฐ ๋กœ๋”ฉ (Lazy Loading)

// ์‚ฌ์šฉ์ž๊ฐ€ ์‹ค์ œ๋กœ ์–ธ์–ด๋ฅผ ๋ณ€๊ฒฝํ•  ๋•Œ๋งŒ ๋กœ๋“œ
const loadTranslations = React.lazy(() => import(`../locales/${language}.json`));

2. ๋ฉ”๋ชจ์ด์ œ์ด์…˜

// ๋ฒˆ์—ญ ํ•จ์ˆ˜ ์ตœ์ ํ™”
const t = useMemo(() => (key, params = {}) => {
  // ๋ฒˆ์—ญ ๋กœ์ง
}, [translations, currentLanguage]);

### 2. **์‹ค์ œ ์‚ฌ์šฉ ์˜ˆ์‹œ ๋ณด๊ฐ•**
```markdown
## ๐Ÿ’ป ์‹ค์ œ ์‚ฌ์šฉ ์˜ˆ์‹œ

### ์ปดํฌ๋„ŒํŠธ์—์„œ ๋‹ค๊ตญ์–ด ์‚ฌ์šฉ
```javascript
import React from 'react';
import { useLanguage } from '../hooks/useLanguage';

const ProductCard = ({ product }) => {
  const { t, currentLanguage } = useLanguage();
  
  return (
    <div className="product-card">
      <h3>{product.name[currentLanguage]}</h3>
      <p>{t('rental_days', { count: product.rentalDays })}</p>
      <span>{t('product_total_count', { count: product.totalCount })}</span>
      
      {/* ๋กœ๋”ฉ ์ƒํƒœ ์ฒ˜๋ฆฌ */}
      {isLoading ? (
        <div>Loading...</div>
      ) : (
        <button>{t('order.rent_now')}</button>
      )}
    </div>
  );
};

์–ธ์–ด ์„ ํƒ ์ปดํฌ๋„ŒํŠธ

const LanguageSelector = () => {
  const { currentLanguage, changeLanguage, availableLanguages } = useLanguage();
  
  const languageNames = {
    ko: 'ํ•œ๊ตญ์–ด',
    en: 'English', 
    ja: 'ๆ—ฅๆœฌ่ชž',
    zh: '็น้ซ”ไธญๆ–‡'
  };
  
  return (
    <select 
      value={currentLanguage} 
      onChange={(e) => changeLanguage(e.target.value)}
    >
      {availableLanguages.map(lang => (
        <option key={lang} value={lang}>
          {languageNames[lang]}
        </option>
      ))}
    </select>
  );
};

### 3. **์นด๋ฉ”๋ผ ๋ Œํƒˆ ์„œ๋น„์Šค ํŠนํ™” ๋‚ด์šฉ ์ถ”๊ฐ€**
```markdown
## ๐Ÿ“ธ ์นด๋ฉ”๋ผ ๋ Œํƒˆ ์„œ๋น„์Šค ํŠนํ™” ๊ณ ๋ ค์‚ฌํ•ญ

### ์ „๋ฌธ ์šฉ์–ด ๋ฒˆ์—ญ์˜ ์–ด๋ ค์›€
```json
{
  "camera_specs": {
    "full_frame": {
      "ko": "ํ’€ํ”„๋ ˆ์ž„",
      "en": "Full Frame",
      "ja": "ใƒ•ใƒซใƒ•ใƒฌใƒผใƒ ", 
      "zh": "ๅ…จๅน…"
    },
    "crop_sensor": {
      "ko": "ํฌ๋กญ์„ผ์„œ",
      "en": "Crop Sensor",
      "ja": "ใ‚ฏใƒญใƒƒใƒ—ใ‚ปใƒณใ‚ตใƒผ",
      "zh": "่ฃๅˆ‡ๆ„Ÿๆธฌๅ™จ"
    },
    "aperture": {
      "ko": "์กฐ๋ฆฌ๊ฐœ",
      "en": "Aperture", 
      "ja": "็ตžใ‚Š",
      "zh": "ๅ…‰ๅœˆ"
    }
  }
}

๋ Œํƒˆ ๊ธฐ๊ฐ„ ํ‘œํ˜„์˜ ๋‹ค๊ตญํ™”

// ๊ฐ ์–ธ์–ด๋ณ„ ๋‚ ์งœ/๊ธฐ๊ฐ„ ํ‘œํ˜„ ์ฐจ์ด ๊ณ ๋ ค
const formatRentalPeriod = (days, language) => {
  const formatters = {
    ko: (d) => `${d}์ผ๊ฐ„`,
    en: (d) => `${d} day${d > 1 ? 's' : ''}`,
    ja: (d) => `${d}ๆ—ฅ้–“`,
    zh: (d) => `${d}ๅคฉ`
  };
  
  return formatters[language](days);
};

### 4. **๋งˆ๋ฌด๋ฆฌ ๋ถ€๋ถ„ ๋ณด์™„**
```markdown
## ๐ŸŽฏ ๋งˆ์น˜๋ฉฐ

### ๐Ÿ“ˆ ํ”„๋กœ์ ํŠธ ์„ฑ๊ณผ
- **์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ๊ฐœ์„ **: ์–ธ์–ด๋ณ„ ์ดํƒˆ๋ฅ  15% ๊ฐ์†Œ
- **๊ธ€๋กœ๋ฒŒ ํ™•์žฅ**: ์ผ๋ณธ/๋Œ€๋งŒ ์‹œ์žฅ ์ง„์ถœ ์„ฑ๊ณต
- **๊ฐœ๋ฐœ ํšจ์œจ์„ฑ**: ๋ฒˆ์—ญ ํ‚ค ๊ด€๋ฆฌ ์ž๋™ํ™”๋กœ ์œ ์ง€๋ณด์ˆ˜ ์‹œ๊ฐ„ 50% ๋‹จ์ถ•

### ๐Ÿ”ฎ ํ–ฅํ›„ ๊ณ„ํš
1. **AI ๋ฒˆ์—ญ ๋„๊ตฌ ์—ฐ๋™**: ์ดˆ๊ธฐ ๋ฒˆ์—ญ ์ž‘์—… ์ž๋™ํ™”
2. **๋ฒˆ์—ญ ํ’ˆ์งˆ ๊ด€๋ฆฌ**: ๋„ค์ดํ‹ฐ๋ธŒ ๊ฒ€์ˆ˜์ž ํ”ผ๋“œ๋ฐฑ ์‹œ์Šคํ…œ
3. **๋‹ค๊ตญ์–ด SEO ์ตœ์ ํ™”**: ์–ธ์–ด๋ณ„ ๋ฉ”ํƒ€ ํƒœ๊ทธ ์ž๋™ ์ƒ์„ฑ

### ๐Ÿ’ก ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž๋“ค์„ ์œ„ํ•œ ํŒ
- ๋ฒˆ์—ญ ํ‚ค๋Š” **์˜๋ฏธ ์ค‘์‹ฌ**์œผ๋กœ ๋„ค์ด๋ฐ (`login_button`๋ณด๋‹ค `auth.login`)
- **์ปจํ…์ŠคํŠธ ์ •๋ณด** ํฌํ•จ (`button_save`๋ณด๋‹ค `order.save_button`)
- ๋ฒˆ์—ญ ํŒŒ์ผ **๋ฒ„์ „ ๊ด€๋ฆฌ** ํ•„์ˆ˜ (git์—์„œ ์ถฉ๋Œ ๋ฐฉ์ง€)

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋น ๋ฅผ ์ˆ˜๋„ ์žˆ์ง€๋งŒ, **์นด๋ฉ”๋ผ ๋ Œํƒˆ**์ด๋ผ๋Š” ์ „๋ฌธ ๋ถ„์•ผ์˜ ์ •ํ™•ํ•œ ๋ฒˆ์—ญ์„ ์œ„ํ•ด์„œ๋Š” ์ง์ ‘ ๊ตฌํ˜„์ด ๋” ์ ํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค.

**์ด ๊ฐœ๋ฐœ ๊ธฐ๊ฐ„**: 1์ฃผ (๊ตฌํ˜„ 2์ผ + ๋ฒˆ์—ญ ์ž‘์—… 6์ผ)  
**ํŒ€ ๋งŒ์กฑ๋„**: โญโญโญโญโญ (5/5)  
**์‚ฌ์šฉ์ž ๋งŒ์กฑ๋„**: ์–ธ์–ด๋ณ„ ํ‰๊ท  4.8/5์ 
profile
โ€œEverything comes to him who hustles while he waitsโ€ ํ•ญ์ƒ ์ตœ๊ณ ๊ฐ€ ๋˜๊ธฐ ์œ„ํ•ด ๊พธ์ค€ํžˆ ๋…ธ๋ ฅํ•˜๋ฉฐ ์„ฑ์žฅํ•ด ๋‚˜์•„๊ฐ€๋Š” Front-End ๊ฐœ๋ฐœ์ž ๊ถŒ์ค€ํ˜•์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€