React - JSX에서 자바스크립트 사용하기

반응형

JSX는 리액트에서 UI를 구성하는 기본적인 문법으로

자바스크립트 코드 안에서 HTML과 유사한 구조를 작성할 수 있도록 도와준다.

하지만 실제로는 자바스크립트의 확장 문법이므로 몇 가지 차이점을 이해해야한다.

천천히 알아보자.


1. 기본 JSX 문법 이해하기

JSX는 자바스크립트의 확장 문법이므로

return문 안에서 HTML과 비슷한 코드를 작성할 수 있다.

 

▼ HTML 코드처럼 JSX 작성하기

function App() {

  return (
    <>
      <h1>Vite + React</h1>
    </>
  )
}

export default App

<>는 프래그먼트(Fragments) 이며 이전 글을 참고하면 되고

h1 태그는 마치 HTML을 작성하는 것처럼 보이지만 실제로는 JSX 문법이다.


2. JSX에서 자바스크립트 표현식 사용하기

JSX 안에서 자바스크립트 코드를 사용하려면 중괄호 {} 를 사용해야한다.

 

▼ 자바스크립트 변수를 JSX에서 사용하기

function App() {
  const name = '섭이';
  return (
    <>
      <h1>안녕하세요 {name}님</h1>
    </>
  )
}
export default App

위와 같이 {name} -> 중괄호 안에 자바 스크립트 변수를 삽입할 수 있다.

 

▼ 자바스크립트 연산 사용하기

function App() {
  const a = 10;
  const b = 20;
  return (
    <>
      <p>10+20 = {a + b}</p>
    </>
  )
}
export default App

위와 같이 { a + b } -> 중괄호 안에서 수학 연산이 가능하다.


3. JSX에서 조건문 사용하기

JSX는 if문을 직접 사용할 수 없는 특징을 갖고 있으며

그대신 삼항 연산자 ( ? : )논리 연산자 ( && )를 활용하여 조건을 처리할 수 있다.

 

▼ 삼항 연산자를 사용한 조건부 렌더링

function App() {
  const isLoggedIn = true;
  return (
    <>
      <h1>{isLoggedIn ? "환영합니다!" : "로그인이 필요합니다."}</h1>
    </>
  )
}
export default App

위와 같이 isLoggedIn이 true면 환영합니다, false면 로그인이 필요합니다 를 출력한다.

▼ 논리 연산자를 사용한 조건부 렌더링

function App() {
  const hasNotification = false;
  return (
    <>
      <h1>홈 화면</h1>
      {hasNotification && <p>새로운 공지사항이 있습니다.</p>}
    </>
  )
}
export default App

위와 같이 조건부 렌더링을 사용하여 hasNotfication이 true일 때만 p 태그가 렌더링된다.


4. JSX에서 이벤트 핸들링

JSX에서는 자바스크립트 함수와 이벤트를 다음과 같이 연결할 수 있다.

 

▼ 버튼 클릭 이벤트 핸들링

function App() {
  function handleClick() {
    alert("버튼이 클릭되었습니다.")
  }
  return (
    <>
      <button onClick={handleClick}>버튼</button>
    </>
  )
}
export default App

위와 같이 onClick 이벤트가 발생하면 handleClick 함수가 실행된다.

▼ 이벤트 핸들러에서 함수 호출하기

function App() {
  return (
    <>
      <button onClick={() => {
        alert('버튼 클릭')
      }}>
        버튼
      </button>
    </>
  )
}
export default App

위와 같이 함수가 없어도 화살표 함수로 처리할 수도 있다.


5. JSX에서 반복문 사용하기

JSX에서는 for문을 직접 사용할 수 없는 대신 map()을 활용한다.

 

▼ 배열을 사용하여 리스트 렌더링

function App() {
  const fruit = ['사과', '바나나', '딸기']
  return (
    <>
      <ul>
        {fruit.map((fruit, index) => (
          <li key={index}>{fruit}</li>
        ))}
      </ul>
    </>
  )
}
export default App

위와 같이 map()을 사용하여 리스트를 동적으로 생성한다.

또한key={index}는 리액트에서 리스트의 각 항목은 고유한 key 값을 가져아한다.


6. JSX에서 스타일 적용하기

JSX에서는 CSS를 인라인 스타일 또는 className을 사용하여 적용할 수 있다.

 

▼ 인라인 스타일 적용

function App() {
  const style = {
    color: 'red',
    fontSize: '20px',
    backgroundColor: 'yellow'
  }
  return (
    <>
      <h1 style={style}>스타일 적용</h1>
    </>
  )
}
export default App

위와 같이 JSX에서는 style={{ 속성명 : 값 }} 형태로 CSS를 적용하고

카멜 케이스 기법으로 변환해야한다. (font-size -> fontSize)

 

▼ CSS 클래스 적용

/* App.css */

.title {
  color: red;
  font-weight: bold;
  background-color: yellow;
}
// App.jsx

import './App.css'
function App() {
  return (
    <>
      <h1 className="title">CSS 클래스 적용</h1>
    </>
  )
}
export default App

위와 같이 css 파일을 임포트해서 사용하고

JSX에서 className을 통해 적용한다.


7. JSX에서 다른 컴포넌트 사용하기

리액트에서는 컴포넌트를 만들어서 코드의 재사용성을 높일 수 있다.

코드를 작은 조각(컴포넌트)으로 나눠서 관리하는게 중요하며

다음과 같이 분리하면 각 파일마다 코드가 깔끔해지고 재사용하기 쉬워진다.

 

▼ 컴포넌트 분리하기

먼저 Product.jsx 파일을 생성하고 다음과 같이 작성한다.

// Product.jsx

function Product({ name = "기본 상품" }) {
  return (
    <>
      <h1>{name} 주문하기</h1>
    </>
  )
}

export default Product;

Product라는 컴포넌트를 생성하고 name을 props로 받아서 출력한다.

또한 name이 없으면 "기본 상품" 을 기본값으로 사용한다.

 

▼ App.jsx에서 Product 컴포넌트 가져와서 사용하기

import Product from './Product'

function App() {
  return (
    <>
      <Product name="맥북" />
    </>
  )
}
export default App

Product.jsx에서 만든 Product 컴포넌트를 임포트하고 

Product 컴포넌트에 name 값 "맥북" 을 전달 해서 동적으로 변경 가능하게 만든다.

이러한 동적 컴포넌트를 생성하여 여러개의 product를 만들 수 있다.

import Product from "./Product";

function App() {
  return (
    <div>
      <Product name="맥북" />
      <Product name="iPhone 15" />
      <Product name="iPad Pro" />
    </div>
  );
}

export default App;

 

 

▼ 기본값 적용하는 방법

이부분을 햇갈려 할 수도 있는데

import Product from "./Product";

function App() {
  return (
    <div>
      <Product name="" />
      <Product name="iPhone 15" />
      <Product name="iPad Pro" />
    </div>
  );
}

export default App;

위와 같이 Product name ="" 을 한다고해서

기본값이 적용되는 것이아니다. 

물론 저렇게 작성하고 Product.jsx 파일에서 OR 연산자를 사용하면 되겠지만

정석인 방법은 다음과 같이 작성한다

import Product from "./Product";

function App() {
  return (
    <div>
      <Product />
      <Product name="iPhone 15" />
      <Product name="iPad Pro" />
    </div>
  );
}

export default App;

이렇게 기본 값을 적용할 수 있다.


모든 개념을 적용한 JSX코드

//  main.jsx

import React from "react";
import ReactDOM from "react-dom/client";
import ProductList from "./ProductList";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <ProductList />
  </React.StrictMode>
);
// ProductList.jsx

import Product from "./Product"; // 7: `props`로 컴포넌트 분리
import "./styles.css"; // 6: 스타일 적용

function ProductList() {
  // 5: `map()`을 사용한 리스트 렌더링
  const products = [
    { id: 1, name: "MacBook", model: "Air", price: "1,500,000원", imageUrl: "https://upload.wikimedia.org/wikipedia/commons/thumb/1/1e/MacBook_with_Retina_Display.png/500px-MacBook_with_Retina_Display.png" },
    { id: 2, name: "iPhone", model: "15 Pro", price: "1,200,000원", imageUrl: "https://upload.wikimedia.org/wikipedia/commons/thumb/5/5d/Apple_iPhone_15.png/799px-Apple_iPhone_15.png?20240131050030" },
    { id: 3, name: "iPad", model: "Pro 11", price: "1,100,000원", imageUrl: "https://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Apple_iPad_Pro_11.jpg/500px-Apple_iPad_Pro_11.jpg" },
  ];

  return (
    <div className="container"> {/* 6: `className`으로 스타일 적용 */}
      <h1>상품 목록</h1>
      <ul>
        {products.map((product) => ( // 5: `map()`을 사용한 리스트 렌더링
          <Product
            key={product.id}
            name={product.name}
            model={product.model}
            price={product.price}
            imageUrl={product.imageUrl}
          />
        ))}
      </ul>
    </div>
  );
}

export default ProductList;
// Product.jsx

function Product({ name, model, price, imageUrl }) { // 7: `props` 활용
  return (
    <li className="product-card"> {/* 6: CSS 스타일 적용 */}
      <h2>{`${name} ${model}`}</h2> {/* 2: JSX에서 표현식 사용 */}
      <img src={imageUrl} alt={`${name} 이미지`} style={{ width: "200px" }} /> {/* 6: `style` 적용 */}
      <p>가격: {price}</p>
    </li>
  );
}

export default Product;

 

/* styles.css */

.container {
  text-align: center;
  font-family: Arial, sans-serif;
}

ul {
  list-style: none;
  padding: 0;
}

.product-card {
  display: inline-block;
  width: 250px;
  border: 1px solid #ddd;
  border-radius: 10px;
  padding: 15px;
  margin: 10px;
  text-align: center;
  box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.1);
}

 

반응형

'React' 카테고리의 다른 글

React - props  (0) 2025.02.20
React - 리액트 컴포넌트 (React Component)  (0) 2025.02.19
React - 프래그먼트(Fragments)  (0) 2025.02.13
React - JSX  (0) 2025.02.12
React - main.jsx (index.js)에서 하는 일  (0) 2025.02.12