DEV/React

[React 개발 기초] 3. JSX에서 JavaScript 사용하기

develop-ch94 2026. 6. 24. 10:50

(1) 변수와 상수 - 기본 중의 기본

function UserCard() {
  const userName = '김철수';
  const userAge = 28;
  
  return (
    <div>
      <h2>{userName}</h2>
      <p>나이: {userAge}세</p>
    </div>
  );
}

(2) 객체 사용 - 점(.)으로 접근

function UserProfile() {
  const user = {
    name: '이영희',
    age: 32,
    job: '디자이너'
  };
  
  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.age}세, {user.job}</p>
    </div>
  );
}

(3) 함수 호출 - 복잡한 로직은 함수로

function Greeting() {
  function getGreeting(hour) {
    if (hour < 12) return '좋은 아침입니다';
    if (hour < 18) return '좋은 오후입니다';
    return '좋은 저녁입니다';
  }
  
  const currentHour = new Date().getHours();
  
  return <h1>{getGreeting(currentHour)}</h1>;
}

(4) 조건 표현식 - 삼항 연산자

function StatusBadge({ status }) {
  return (
    <span className={status === 'active' ? 'badge-green' : 'badge-gray'}>
      {status === 'active' ? '활성' : '비횔성}
    </span>
  );
}

 

안티패턴: 중첩 삼항 연산자

// 절대 하지 말 것
<span className={
  status === 'active' ? 'badge-green' :
  status === 'pending' ? 'badge-yellow' :
  status === 'error' ? 'badge-red' :
  'badge-gray'
}>
  {status}
</span>

 

개선: 함수로 분리

function getBadgeClass(status) {
  if (status === 'active') return 'badge-green';
  if (status === 'pending') return 'badge-yellow';
  if (status === 'error') return 'badge-red';
  return 'badge-gray';
}

function StatusBadge({ status }) {
  return <span className={getBadgeClass(status)}>{status}</span>;
}

(5) 배열 메서드 - map과 filter

기본: map - 배열의 각 요소를 JSX로 변환

function FruitList() {
  const fruits = [
    { id: 1, name: '사괴' },
    { id: 2, name: '바나나' },
    { id: 3, name: '오렌지' }
  ];
  
  return (
    <ul>
      {fruits.map(fruit => (
        <li key={fruit.id}>{fruit.name}</li>
      ))}
    </ul>
  );
}

 

응용: filter + map 체이닝

function UserList({ users }) {
  return (
    <ul>
      {users
        .filter(user => user.active)	// 활성 사용자만
        .map(user => (			// JSX로 변환
          <li key={user.id}>{user.name}</li>
        ))}
    </ul>
  );
}

 

안티패턴 #1: key={index}

// ❌ index를 key로 쓰지 마세요
{fruits.map((fruit, index) => (
  <li key={index}>{fruit}</li>
))}
문제점: 배열 순서가 바뀌거나(정렬, 삭제, 추가) 하면 React가 헷갈려서 버그가 생김
특히 입력 폼이 있는 리스트에선 입력값이 엉뚱한 항목으로 옮겨지는 심각한 버그로 이어짐

 

개선: 고유한 ID를 key로

// ✅ 각 항목의 고유 id를 key로
{fruits.map(fruit => (
  <li key={fruit.id}>{fruit.name}</li>
))}
key의 의미: React에게 "이게 그 항목이에요!"라고 알려주는 이름표
이름표가 순번(index)이면, 순서 바뀔 때 이름표도 따라 바뀌어버려서 추적이 안 됨

(6) 템플릿 리터럴 - 문자열 조합

function ProductCard({ product }) {
  return (
    <div className={`product-card ${product.featured ? 'feature' : ''}`}>
      <h3>{product.name}</h3>
    </div>
  );
}

 

안티패턴: 불필요한 템플릿 리터럴

// ❌ 굳이 템플릿 리터럴 쓸 필요 없음
<p>{`₩${product.price.toLocaleString()}`}</p>

// ❌ 이것도 마찬가지
<p>{`재고: ${product.stock}개`}</p>
문제점: 이미 JSX 안이니까 문자열을 그냥 쓰면 됨. 굳이 템플릿 리터럴로 감쌀 필요 없음

 

개선: JSX의 자연스러운 흐름 활용

// ✅ 깔끔!
<p>₩{product.price.toLocaleString()}</p>
<p>재고: {product.stock}개</p>
판단 기준:
템플릿 리터럴은 여러 값을 조합해 하나의 문자열을 만들 때 유용함 (예: className 조합)
JSX 안에서 텍스트 꽂을 땐 그냥 {} 로 충분

(7) 꼭 피해야 할 패턴: 즉시 실행 함수(IIFE)

❌ 안티패턴: JSX 안에서 IIFE

function Dashboard({ score }) {
  return (
    <div>
      <p>점수: {score}</p>
      <p>등급: {
        (() => {
          if (score >= 90) return 'A';
          if (score >= 80) return 'B';
          if (score >= 70) return 'C';
          return 'D';
        })()
      }</p>
    </div>
  );
}

 

🚨 문제점:
 - 읽기 지옥: (() => {})() 이 괄호 지옥
 - 디버깅 어려움: 함수에 이름이 없어서 에러 추적이 힘듦
 - 재사용 불가: 같은 로직을 다른 곳에서 쓸 수 없음

 

✅ 개선: 함수로 분리

function getGrade(score) {
  if (score >= 90) return 'A';
  if (score >= 80) return 'B';
  if (score >= 70) return 'C';
  return 'D';
}

function Dashboard({ score }) {
  return (
    <div>
      <p>점수: {score}</p>
      <p>등급: {getGrade(score)}</p>
    </div>
  );
}