컴포넌트
코드 블록의 Try it Yourself 버튼으로 직접 실행할 수 있다.
구문
1. 영상보기
1-2. 컴포넌트와 프롭스란?
component: 두번이상 사용되는 UI 요소를 사용자정의 태그로 만들어 사용하는 것 props: 컴포넌트에 전달하는 데이터
2. App.js 파일로 컴포넌트의 정의 알아보기
- ./src/App.js 파일을 열고 App() 함수와 App() 함수가 반환하는 값을 보자.
import React from 'react';
function App() {
//App() 컴포넌트를 정의했고,
return (
// App 컴포넌트는 HTML을 반환하고 있다.
<div>
<h1>Hello</h1>
</div>);
}
export default App;
- App() 함수가 정의되어 있고, 이 함수가
<div>Hello</div>를 반환하고 있다. - 바로 App 컴포넌트를 정의한 것이다.
- App() 함수가 반환한 HTML이 리액트 앱 화면에 그려지는 것이다.
3. index.js 파일로 컴포넌트의 사용 알아보기
./src/index.js파일을 열고 이라고 입력한 내용에 집중해 보자.
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('orange'));
console.log(ReactDOM);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
- App 컴포넌트 생김새가 마치 HTML 태그 같다.하지만 HTML에는
<App />이라고 생긴 태그가 없다.실제로<App />는 HTML 태그가 아니기도 하다. - root.render() 의 인자로
<App />을 전달하면 App 컴포넌트가 반환하는 것들을 화면에 그릴 수 있다.아이디가 root인 앨리먼트는 public/index.html에 정의되어 있다. - 리액트는
<App />과 같은 표시를 컴포넌트로 인식하고, 그 컴포넌트가 반환하는 값을 화면에 그려준다.그래서 컴포넌트를 사용할 때<App />가 아니라 App이라고 입력하면 오류가 발생한다. - 여기서 집중할 내용은 리액트는 컴포넌트와 함께 동작하고, 리액트 앱은 모두 컴포넌트로 구성된다.
4. JSX 문법 알아보기
우리는 아직 컴포넌트를 만든 적이 없다.
컴포넌트는 어떻게 만들까? 컴포넌트는 자바스크립트와 HTML을 조합한 **JSX(Javascript XML의 약자로 '자바스크립트에 XML을 추가한 확장형 문법') **라는 문법을 사용해서 만든다. JSX는 HTML과 자바스크립트를 조합한 것으로 별도로 학습할 필요가 없다. 컴포넌트를 만들다 보면 자연스럽게 JSX 문법을 어떻게 사용해야 하는지 알게 된다.
4.1. Orange 컴포넌트 만들기
- src/Orange.js라는 이름의 새로운 파일을 만들어 보자.
- 파일 이름에서 첫 번째 글자는 반드시 대문자로 입력한다.
- 그후 아래의 코드를 입력한다.
import React from 'react';
- 이 코드는 리액트 패키지로 부터 리액트 컴포넌트를 만드는 모듈울 불러온다는 의미이다.
- react 18버전 이후로 위의 import 는 생략가능하다
- 컴포넌트를 만들때 때 중요한 규칙은 이름은 대문자로 시작해야 한다는 점이다.
4.2. Orange 컴포넌트 작성하기
- 다음과 같이 Orange() 함수를 작성해 보자.
import React from 'react';
const Orange = () => {
return (
<h3>Orange</h3> // HTML이 아니라 JSX이다.
);
};
- Orange 컴포넌트의 기본 틀이 완성되었다.
- 이제 컴포넌트가 반환할 값을 입력하면 된다. 이때 컴포넌트가 반환할 값은 JSX문법으로 작성한다.
4.3. 마지막 줄에 export default Orange;를 추가
import React from 'react';
const Orange = () => {
return (
<h3>Orange</h3> // HTML이 아니라 JSX이다.
);
};
export default Orange;
- export default Orange; 를 추가하면 다른 파일에서 Orange 컴포넌트를 사용할 수 있다.
- 컴포넌트란 재사용 가능한 UI를 의미하므로 이 파일은 다른 파일에서 여러번 불러서 사용한다는 의미이다.
- 그렇기 때문에 반드시 내보내기를 해야한다. 이제 완성한 컴포넌트를 사용해 보자.
4.4. Orange 컴포넌트 사용하기
를 삭제후 아래와 같이 Orange 컴포넌트를 추가한다.<React.StrictMode>- StrictMode 는 애플리케이션 내의 잠재적인 문제를 알아내기 위한 도구이다. 사용하면 좋으나 초심자의 개발단계에서는 사용할 일이 거의 없으므로 삭제한다. 실무에서는 사용하는것을 추천한다.
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import Orange from './Orange';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('orange'));
root.render(
<App /><Orange />);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
4.5. index.js를 원래대로 돌려 놓자.
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
~~import Orange from './Orange';~~
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
4.6. App.js 파일의 App 컴포넌트에 Orange 컴포넌트 임포트하기
import Orange from './Orange'; //같은 경로의 Orange 모듈 내 Orange 컴포넌트를 불러옴
function App() {
return (
<div className='App'>
<h1>HELLO</h1>
<Orange />
</div>);
}
export default App;
- 여기까지 확인하면 'orange'가 출력된다.
4.7. 개발자 도구에서 Orange 컴포넌트를 살펴보자.
- 개발자 도구의 [Element] 탭을 열어 코드를 살펴보면, 리액트가
<Orange />를 해석해서로 태그로 만들었다. 이것이 컴포넌트와 JSX가 리액트에서 동작하는 방식이다. 컴포넌트는 JSX로 만들고, JSX는 자바스크립트와 HTML을 조합한 문법을 사용한다는 말이 이제는 조금 이해가 될 것이다.
4.8. Orange.js 파일을 삭제하고 App.js 파일 수정하기
- Orange.js 파일을 삭제하고 App.js 파일에서 Orange 컴포넌트를 import하는 코드를 지우자.
import React from 'react';
function App() {
return (
<div>
<h1>Hello</h1>
<Orange />
</div>);
}
export default App;
- 위 코드를 실행하면 오류 메세지가 나온다. 오류 메세지의 내용은 'App.js 파일에 Orange가 없어서 컴파일에 실패했다'라는 내용이다. 이제 이 오류를 해결하기 위해 App.js 파일 안에 Orange 컴포넌트를 만든 다음 Orange 컴포넌트를 사용해 보자.

4.9. App 컴포넌트 안에 Orange 컴포넌트 만들기
- src/App.js를 열고 다음과 같이 App 컴포넌트를 수정해서 Orange 컴포넌트를 만들어 보자. 즉, App.js 파일에 Orange() 함수를 만들어 보자.
import React from 'react';
const Orange = () => {
return <h3>Orange</h3>;
};
function App() {
return (
<div>
<h1>Hello</h1>
<Orange />
</div>);
}
export default App;
- 에러를 일으키며 중지되었던 앱이 다시 정상으로 작동한다. App.js 파일 안에 Orange 컴포넌트를 만들었고, Orange 컴포넌트를 App 컴포넌트 안에서 사용했다.
- 컴포넌트내에 중첩하여 컴포넌트를 작성할수 있다.
- 중첩 컴포넌트는 import 문이 없이도 불러오기가 가능하다.
5. jsx 정리
Info: 💡 jsx 란 자바스크립트로 UI요소를 반환하는 컴포넌트를 만드는 문법이다.
🚩 컴포넌트규칙
1. 파일명은 대문자로 시작
1. 반드시 `return` 으로 반환값이 있어야 하며 `return` 문의 반환값은 반드시 UI요소(즉 유사태그) 이어야 한다.
1. 최상위 요소는 단 한개만 가능하다.
1. 중첩컴포넌트는 import 를 생략해도 된다.
6. props
**props는 컴포넌트간 전달하는 데이터를 말한다. 함수의 매개변수라는 개념을 알고 있다면 매개변수를 이용하면 함수를 효율적으로 재사용할 수 있다는 것을 알 것이다. 컴포넌트의 props도 비슷하다. **
props를 사용하면 컴포넌트를 효율적으로 재사용할 수 있다.
6.1. 컴포넌트 여러 개 사용해 보기
- 만약 우리가 만든 앱에 음식 목록이 있고, 그 음식목록을 컴포넌트로 표현한다고 해보자. 그런 상황을 가정하기 위해 Orange 컴포넌트의 이름을 Foods로 바꿔 보자.
/* import Orange from './Orange'; */
const Foods = () => {
return <h3>Foods</h3>;
};
function App() {
return (
<div className='App'>
<h1>HELLO</h1>
<Foods />
</div>);
}
export default App;
- Foods컴포넌트 1개가 음식목록 1개라고 생각하면 만약 음식목록을 15개 그리려면 어떻게 해야 할까?
6.2. 다음과 같이 Foods컴포넌트를 15개 복사해서 붙여 넣어 보자
import React from 'react';
const Foods = () => {
return <h3>Foods</h3>;
};
function App() {
return (
<div>
<h1>Hello</h1>
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
<Foods />
</div>);
}
export default App;
- 위와 같이 코드를 구성한다면 Foods컴포넌트가 15개나 되는데 출력하는 값이 모두Foods로 같다는 것도 문제이다.컴포넌트가 서로 다른 값을 출력해야 앱의 목록을 구현할 수 있을 텐데...그래서 컴포넌트로 데이터를 보내는 방법이 필요하다. 그 방법이 props이다.
6.3. props로 컴포넌트에 데이터 전달하기1
- ./src/App.js 파일의 컴포넌트의 이름을 Foods에서 Fruit로 변경하자. 그리고 Foods 컴포넌트는 모두 삭제하자.
- h1 의 컨텐츠도 hello 로 변경한다.
/* import Orange from './Orange'; */
const Fruit = () => {
return <h1>I like orange</h1>;
};
function App() {
return (
<div className='App'>
<h1>HELLO</h1>
<Fruit />
</div>);
}
export default App;
- 임시로 과일을 주제로 리액트 앱을 만들어 볼 것이다. 그냥 과일 앱이라고 부르자. props는 컴포넌트로 데이터를 보낼 때 사용할 수 있다고 했다. 이제 props를 이용하여 Fruit 컴포넌트에 데이터를 보내 보자.
6.4. props로 컴포넌트에 데이터 전달하기2
- ./src/App.js 파일의 를 로 수정해 보자. fav props의 값으로 "banana"를 추가하는 것이다.
import React from 'react';
function Fruit() {
return <h1>I like orange</h1>;
}
function App() {
return (
<div>
<h1>Hello</h1>
<Fruit fav='banana' />
</div>);
}
export default App;
- 이게 바로 props를 이용하여 Fruit 컴포넌트에 데이터를 보내는 방법이다.Fruit 컴포넌트에 사용한 props의 이름은 fav이고, fav에 "banana"라는 값을 담아 Fruit 컴포넌트에 보낸 것이다.
- props에는 불리언 값(true, false), 숫자, 배열과 같은 다양한 형태의 데이터를 담을 수 있다.여기서 주의할 점은 props에 있는 데이터는 문자열인 경우를 제외하면 모두 중괄호 ****
\{\}****로 값을 감싸야 한다는 점이다.
6.5. Fruit 컴포넌트에 props 전달하기3
- ./src/App.js 파일의 Fruit 컴포넌트에 something, papapapa props를 추가해 보자. 그리고 수정한 파일을 저장.
import React from 'react';
function Fruit() {
return <h1>I like orange</h1>;
}
function App() {
return (
<div>
<h1>Hello</h1>
<Fruit fav='banana' something={true} papapapa={['hello', 1, 2, 3, 4, true]} />
</div>);
}
export default App;
jsx 문서 내에서 자바스크립트 표현식의 출력은 `{}`를 사용한다.
something 의 값은 자바스크립트의 논리자료형 true 이므로 `{}`로 묶어야 자바스크립트 표현식으로 렌더링할수 있다.
6.6. Fruit 컴포넌트에 props 전달하기4
- ./src/App.js 파일을 수정한 상태에서 리액트 앱을 실행해 보자.
- 그러면 아무런 변화가 없을 것이다. 왜 그럴까? Fruit 컴포넌트에 props를 보내기만 했을 뿐 아직 사용하지 않았기 때문이다.그럼 Fruit 컴포넌트에서 props를 사용하려면 어떻게 해야 할까?
6.7. Fruit 컴포넌트에 props 전달하기5
- ./src/App.js 파일에서 일단 Fruit 컴포넌트의 인자로 전달된 props를 출력해 보자.
const Fruit = (props) => {
console.log(props);
return <h1>I like orange</h1>;
};


- 리액트의 jsx는 return 함수내의 반환값이 태그인것을 의미한다.
- 그러므로 return 이전의 코드는 jsx 가 아닌 자바스크립트 이므로 바닐라자바스크립트 문법을 사용할수 있다.
6.8. Fruit 컴포넌트에 props 전달하기6
- 크롬의 개발자 도구를 실행해서 [Console] 탭을 눌러 보자.
- Fruit 컴포넌트에 전달한 props(fav, something, papapapa)를 속성으로 가지는 객체(Object)가 출력되었다. fav, something, papapapa의 값이 Fruit 컴포넌트의 첫 번째 인자(props)로 전달되는 과정을 확인할 수 있다.
6.9. Fruit 컴포넌트에 props 전달하기7 (props 다시 한번 사용하기)
- ./src/App.js 파일에서 코드를 다음과 같이 수정해보자. 일단 something, papapapa, props는 사용하지 않을 거니까 지우자.
...
function App() {
return (
<div className='App'>
<h1>HELLO</h1>
<Fruit fav='banana' />
</div>);
}
...
- 그러면 콘솔에 {fav: "banana"}만 출력될 것이다. 만약 문자열 "banana"를 화면에 그대로 출력하고 싶다면 어떻게 해야 할까?
6.10. Fruit 컴포넌트에 props 전달하기8
/src/App.js파일에서 Fruit 컴포넌트에 있는 데이터 "banana"를 화면에 출력하자면 props.fav를 중괄호로 감싸면 된다.
...
const Fruit = (props) => {
console.log(props.fav);
return <h3>{props.fav}</h3>;
};
...
6.11. 구조 분해 할당으로 props 사용하기
- 자바스크립트의 ES6 문법 중 구조 분해 할당(destrueturing-assignment)를 사용하면 점 연산자를 사용하지 않아도 된다. 다음은 Fruit 컴포넌트로 전달한 fav props를 Fruit 컴포넌트(함수)에서 = props; 와 같은 방법으로 사용한 예이다.
/* import Orange from './Orange'; */
const Fruit = (props) => {
//const fav = props.fav;
const { fav } = props;
console.log(fav);
return <h3>{fav}</h3>;
};
function App() {
return (
<div className='App'>
<h1>HELLO</h1>
<Fruit fav='banana' />
</div>);
}
export default App;
- props에 포함된 데이터의 개수가 적으면 점 연산자를 사용하여 props.fav와 같은 방법으로 사용해도 불편하지 않지만, props에 포함된 데이터의 개수가 많아지면 매번 props.fav와 같은 방법으로 사용하면 불편하다. 이 경우 구조 분해 할당을 사용하면 편리하다.
- 구조 분해 할당은 객체에 있는 키값을 편하게 추출할 수 있게 해주는 자바스크립트 문법이다.
6.12. 여러 개의 컴포넌트에 props 사용하기
- Fruit 컴포넌트를 3개 추가하고 fav props의 값이 서로 다르도록 코드를 수정하자.
import React from 'react';
function Fruit({ fav }) {
return <h1>I like{fav}</h1>;
}
function App() {
return (
<div>
<h1>Hello</h1>
<Fruit fav='banana' />
<Fruit fav='orange' />
<Fruit fav='apple' />
<Fruit fav='melon' />
</div>);
}
export default App;
- 이번 액션에서는 Fruit 컴포넌트를 4개 사용해 각 컴포넌트에 전달한 fav props를 출력했다. 각각의 fav props에는 서로 다른 값이 들어 있으니까 같은 컴포넌트를 사용해도 서로 다른 문장이 출력된 것이다. 이렇게 하는 것을 컴포넌트 재 사용라고 한다.
- 배운 내용을 정리해 보자.
- 컴포넌트가 무었인지 알아보고 JSX를 공부했다.
- JSX는 단지 HTML과 자바스크립트를 조합한 문법이다.
- JSX를 이용해서 컴포넌트를 작성했다. (컴포넌트의 이름은 대문자로 시작함에 유의!)
- 컴포넌트에 데이터를 전달할 때는 props 사용하면 된다.
- 컴포넌트에 props를 전달하면 props에 있는 데이터가 하나의 객체로 변환되어 컴포넌트(함수)의 인자로 전달되고, 이걸 받아서 컴포넌트(함수)에서 사용할 수 있었다. ES6의 구조 분해 할당을 사용하면 props를 좀 더 편리한 방법으로 사용할 수 있었고, 앱을 만들 때 이 패턴이 사용되니까 잘 기억하고 넘어가자.
7. 여기까지 깃허브에 올리기
$ git add .
$ git commit -m "03 깃허브에 리액트 앱 업로드하기"
$ git push origin main