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 |