✍ 리액트 공식 사이트 http://react.dev 에서 배우게 될 내용
- components(컴포넌트) 생성과 중첩
- 마크업 및 스타일 추가 방법
- 데이터를 표시하는 방법
- conditions(조건) 및 목록(lists) 렌더링 하는 방법
- 이벤트 응답과 화면 업데이트 방법
- 컴포넌트 간에 데이터를 공유하는 방법
📚 Creating and nesting components : 컴포넌트 생성과 중첩
리액트 앱들은 컴포넌트들로 구성된다. 컴포넌트는 고유의 로직과 외관을 갖는 UI(사용자 인터페이스)의 일부이다.
컴포넌트는 버튼만큼 작을 수도 있고, 전체 페이지만큼 클 수도 있다.
리액트 컴포넌트는 마크업을 반환하는 자바스크립트 함수이다:
function MyButton() {
return (
<button>I'm a button</button>
);
}
위 코드는 함수형 컴포넌트로 return안에 마크업 언어인 <button>태그를 MyButton 이라는 컴포넌트로 선언하였다.
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
컴포넌트를 만들 때는 대문자로 시작한다는 점을 주의한다. 그래야 해당요소가 리액트 컴포넌트라는 것을 알 수 있다.
리액트 컴포넌트는 첫글자를 대문자로, HTML태그는 소문자로 작성한다.
해당 요소들을 App.js에 작성해서 결과를 알아보도록 한다.
// App.js
function MyButton() {
return (
<button>
I'm a button
</button>
);
}
export default function MyApp() {
return (
<div>
<h1>Welcome to my app</h1>
<MyButton />
</div>
);
}
실행 결과
Welcome to my app
export default 키워드는 파일의 메인 컴포넌트를 지정한다. 만약 자바스크립트 구문이 익숙하지 않다면, MDN과 javascript.info 에서 참고자료를 확인한다.
📚 Writing markup with JSX : JSX로 마크업 쓰기
위에서 보신 마크업 구문은 JSX라고 한다. 선택 사항이지만 대부분의 리액트 프로젝트는 JSX를 사용한다. 로컬 개발에 권장하는 모든 도구는 JSX를 즉시 지원한다.
JSX는 HTML보다 더 엄격하다. <br />와 같은 단일 태그는 반드시 닫는 태그를 표시해줘야 한다. 또한 컴포넌트는 여러 개의 JSX 태그를 return할 수도 없다. 공유된 상위 태그를 <div>.../div> 또는 빈 태그 <>...</> 와 같이 묶어야 한다 :
function AboutPage() {
return (
<>
<h1>About</h1>
<p>Hello there.<br />How do you do?</p>
</>
);
}
JSX로 포팅할 HTML이 많다면 온라인 컨버터를 사용할 수 있다.

📚 Adding styles : 스타일 추가하기
React에서 className으로 CSS의 class를 지정한다. HTML의 class속성과 동일하게 작동한다
<img className="avatar" />
리액트에서 className으로 선언한 요소에 스타일을 CSS파일에서 선언해보도록 하겠다.
/* CSS */
.avatar {
border-radius: 50%;
}
리액트는 CSS 파일을 추가하는 방법을 규정하지 않는다. 가장 간단한 경우에는 HTML에 <link> 태그를 추가할 것이다. 빌드 도구나 프레임워크를 사용하는 경우, CSS 파일을 프로젝트에 추가하는 방법은 해당 문서를 참조하면 된다.
( 리액트 프로젝트의 App.css에 작성하거나 index.html에서 선언해주면 될거 같다.)
📚 Displaying data : 데이터 표시
JSX는 마크업을 JavaScript에 넣을 수 있게 해준다. { 중괄호 }를 사용하면 코드에서 변수를 추출하여 사용자에게 표시할 수 있다. 다음 user.name을 예로 들어보자 :
return (
<h1>
{user.name}
</h1>
);
JSX 속성에서도 중괄호{ }를 사용하여 JavaScript로 "이스케이프(escape)"할 수 있지만 따옴표 대신 중괄호를 사용해야 한다. 예를 들어, className="avatar"는 "avatar" 문자열을 CSS 클래스로 전달하지만, src={user.imageUrl}는 JavaScript에서 user.imageUrl 변수 값을 읽어와 해당 값을 src 속성으로 전달한다.
return (
<img
className="avatar"
src={user.imageUrl}
/>
);
JSX 중괄호 내에는 더 복잡한 표현식도 넣을 수 있다. 예를 들면, 문자열 연결을 할 수 있다:
// App.js
const user = {
name: 'Hedy Lamarr',
imageUrl: 'https://i.imgur.com/yXOvdOSs.jpg',
imageSize: 90,
};
export default function Profile() {
return (
<>
<h1>{user.name}</h1>
<img
className="avatar"
src={user.imageUrl}
alt={'Photo of ' + user.name}
style={{
width: user.imageSize,
height: user.imageSize
}}
/>
</>
);
}
실행 결과
Hedy Lamarr
위 예제에서, style={ { } }는 특별한 문법이 아니라, style={ } JSX 중괄호 내의 일반적인 { } 객체다. style 속성은 스타일이 JavaScript 변수에 의존할 때 사용할 수 있다.
📚 Conditional rendering : 조건부 렌더링
React에서는 조건을 작성하는 데 특별한 문법이 없다. 대신, 일반적인 JavaScript 코드를 작성할 때 사용하는 기술을 그대로 사용한다. 예를 들어, JSX를 조건에 따라 조건적으로 포함시키기 위해 if 문을 사용할 수 있다:
let content;
if (isLoggedIn) {
content = <AdminPanel />;
} else {
content = <LoginForm />;
}
return (
<div>
{content}
</div>
);
코드를 더 간결하게 작성하려면 삼항 연산자(conditional ? operator)를 사용할 수 있다. if 문과 달리 이 연산자는 JSX 내부에서도 작동한다:
<div>
{isLoggedIn ? (
<AdminPanel />
) : (
<LoginForm />
)}
</div>
else 가 필요하지 않은 경우, 더 간결한 논리 && 구문을 사용할 수도 있다:
<div>
{isLoggedIn && <AdminPanel />}
</div>
이러한 모든 접근 방식은 속성을 조건적으로 지정하는 데도 동일하게 작동한다. JavaScript 구문 중 일부가 익숙하지 않다면 항상 if...else를 사용하여 시작할 수 있다.
📚 Rendering lists : 목록 렌더링
리스트 형태의 컴포넌트를 렌더링하기 위해 for 루프와 배열의 map() 함수와 같은 JavaScript 기능을 활용할 것이다.
예를 들어, 제품 목록 배열이 있다고 가정해보겠다:
const products = [
{ title: 'Cabbage', id: 1 },
{ title: 'Garlic', id: 2 },
{ title: 'Apple', id: 3 },
];
컴포넌트 내에서 map() 함수를 사용하여 제품 배열을 <li> 아이템의 배열로 변환하는 예:
const listItems = products.map(product =>
<li key={product.id}>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
<li>에는 key 속성이 있는 것을 주목한다. 리스트의 각 항목에 대해 해당 항목을 형제들 중에서 고유하게 식별하는 문자열 또는 숫자를 전달해야 한다. 일반적으로 키는 데이터에서 가져와야 한다. 예를 들어 데이터베이스 ID와 같은 값이 될 수 있다. React는 키를 사용하여 나중에 항목을 삽입, 삭제 또는 재정렬할 때 무엇이 발생했는지를 알게 된다.
// App.js
const products = [
{ title: 'Cabbage', isFruit: false, id: 1 },
{ title: 'Garlic', isFruit: false, id: 2 },
{ title: 'Apple', isFruit: true, id: 3 },
];
export default function ShoppingList() {
const listItems = products.map(product =>
<li
key={product.id}
style={{
color: product.isFruit ? 'magenta' : 'darkgreen'
}}
>
{product.title}
</li>
);
return (
<ul>{listItems}</ul>
);
}
실행 결과
- Cabbage
- Garlic
- Apple
📚 Responding to events : 이벤트 응답하기
이벤트에 응답하려면 컴포넌트 내에서 이벤트 핸들러 함수를 선언할 수 있다:
function MyButton() {
function handleClick() {
alert('You clicked me!');
}
return (
<button onClick={handleClick}>
Click me
</button>
);
}
onClick={handleClick}에서 괄호가 없음에 주목한다! 이벤트 핸들러 함수를 직접 호출하지 않고 함수를 전달만 하면 된다. 사용자가 버튼을 클릭할 때 React가 이벤트 핸들러를 호출한다.
📚 Updating the screen : 화면 업데이트
종종 컴포넌트가 특정 정보를 "기억"하고 표시하게 하고 싶을 때가 있다. 예를 들어, 버튼이 클릭된 횟수를 세고 싶을 수 있다. 이를 위해 컴포넌트에 상태를 추가하도록 한다.
우선, 'react' 라이브러리로 부터 useState를 추가하도록 한다.
import { useState } from 'react';
이제 아래와 같이 컴포넌트 내에서 상태 변수를 선언할 수 있다:
function MyButton() {
const [count, setCount] = useState(0);
// ...
`useState`를 통해 두 가지를 얻게 된다: 현재 상태(`count`)와 상태를 업데이트하는 함수(`setCount`)다. 어떤 이름으로도 지정할 수 있지만, 일반적으로 `[something, setSomething]` 형태로 작성하는 것이 관례다.
버튼이 처음 표시될 때 `count`는 0이 된다. 왜냐하면 `useState(0)`에 0을 전달했기 때문이다. 상태를 변경하려면 `setCount()`를 호출하고 새로운 값을 전달하면 된다. 이 버튼을 클릭하면 카운터가 증가한다.
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
React는 컴포넌트 함수를 다시 호출한다. 이번에는 `count`가 1이 되고 2 계속해서 증가할 것이다.
동일한 컴포넌트를 여러 번 렌더링하는 경우, 각각이 고유한 상태를 가지게 된다. 각 버튼을 따로 클릭해 보자:
import { useState } from 'react';
export default function MyApp() {
return (
<div>
<h1>Counters that update separately</h1>
<MyButton />
<MyButton />
</div>
);
}
function MyButton() {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<button onClick={handleClick}>
Clicked {count} times
</button>
);
}
실행 결과
각 버튼이 자체적으로 상태를 "기억"하고 다른 버튼에 영향을 미치지 않는 것을 주목한다.
'React' 카테고리의 다른 글
| 보수교육 2일차 (1) | 2024.04.28 |
|---|---|
| 보수교육 1일차 (1) | 2024.04.27 |
| [React] React와 express.js를 활용한 게시판 만들기(2) (0) | 2024.01.21 |
| [React] React와 express.js를 활용한 게시판 만들기(1) (0) | 2024.01.20 |
| [React] Props에 대한 설명과 예시 (0) | 2024.01.19 |