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

4.9. App 컴포넌트 안에 Orange 컴포넌트 만들기
- src/App.js를 열고 다음과 같이 App 컴포넌트를 수정해서 Orange 컴포넌트를 만들어 보자. 즉, App.js 파일에 Orange() 함수를 만들어 보자.
1import React from 'react';2
3const Orange = () => {4 return <h3>Orange</h3>;5};6
7function App() {8 return (9 <div>10 <h1>Hello</h1>11 <Orange />12 </div>);13}14
15export default App;- 에러를 일으키며 중지되었던 앱이 다시 정상으로 작동한다. App.js 파일 안에 Orange 컴포넌트를 만들었고, Orange 컴포넌트를 App 컴포넌트 안에서 사용했다.
- 컴포넌트내에 중첩하여 컴포넌트를 작성할수 있다.
- 중첩 컴포넌트는 import 문이 없이도 불러오기가 가능하다.
5. jsx 정리
정보
💡 jsx 란 자바스크립트로 UI요소를 반환하는 컴포넌트를 만드는 문법이다.
🚩 컴포넌트규칙
- 파일명은 대문자로 시작
- 반드시
return으로 반환값이 있어야 하며return문의 반환값은 반드시 UI요소(즉 유사태그) 이어야 한다. - 최상위 요소는 단 한개만 가능하다.
- 중첩컴포넌트는 import 를 생략해도 된다.
6. props
**props는 컴포넌트간 전달하는 데이터를 말한다. 함수의 매개변수라는 개념을 알고 있다면 매개변수를 이용하면 함수를 효율적으로 재사용할 수 있다는 것을 알 것이다. 컴포넌트의 props도 비슷하다. **
props를 사용하면 컴포넌트를 효율적으로 재사용할 수 있다.
6.1. 컴포넌트 여러 개 사용해 보기
- 만약 우리가 만든 앱에 음식 목록이 있고, 그 음식목록을 컴포넌트로 표현한다고 해보자. 그런 상황을 가정하기 위해 Orange 컴포넌트의 이름을 Foods로 바꿔 보자.
1/* import Orange from './Orange'; */2
3const Foods = () => {4 return <h3>Foods</h3>;5};6
7function App() {8 return (9 <div className='App'>10 <h1>HELLO</h1>11 <Foods />12 </div>);13}14
15export default App;- Foods컴포넌트 1개가 음식목록 1개라고 생각하면 만약 음식목록을 15개 그리려면 어떻게 해야 할까?
6.2. 다음과 같이 Foods컴포넌트를 15개 복사해서 붙여 넣어 보자
1import React from 'react';2
3const Foods = () => {4 return <h3>Foods</h3>;5};6
7function App() {8 return (9 <div>10 <h1>Hello</h1>11 <Foods />12 <Foods />13 <Foods />14 <Foods />15 <Foods />16 <Foods />17 <Foods />18 <Foods />19 <Foods />20 <Foods />21 <Foods />22 <Foods />23 <Foods />24 <Foods />25 <Foods />26 <Foods />27 </div>);28}29
30export default App;- 위와 같이 코드를 구성한다면 Foods컴포넌트가 15개나 되는데 출력하는 값이 모두Foods로 같다는 것도 문제이다.컴포넌트가 서로 다른 값을 출력해야 앱의 목록을 구현할 수 있을 텐데…그래서 컴포넌트로 데이터를 보내는 방법이 필요하다. 그 방법이 props이다.
6.3. props로 컴포넌트에 데이터 전달하기1
- ./src/App.js 파일의 컴포넌트의 이름을 Foods에서 Fruit로 변경하자. 그리고 Foods 컴포넌트는 모두 삭제하자.
- h1 의 컨텐츠도 hello 로 변경한다.
1/* import Orange from './Orange'; */2
3const Fruit = () => {4 return <h1>I like orange</h1>;5};6
7function App() {8 return (9 <div className='App'>10 <h1>HELLO</h1>11 <Fruit />12 </div>);13}14
15export default App;- 임시로 과일을 주제로 리액트 앱을 만들어 볼 것이다. 그냥 과일 앱이라고 부르자. props는 컴포넌트로 데이터를 보낼 때 사용할 수 있다고 했다. 이제 props를 이용하여 Fruit 컴포넌트에 데이터를 보내 보자.
6.4. props로 컴포넌트에 데이터 전달하기2
- ./src/App.js 파일의 를 로 수정해 보자. fav props의 값으로 “banana”를 추가하는 것이다.
1import React from 'react';2
3function Fruit() {4 return <h1>I like orange</h1>;5}6
7function App() {8 return (9 <div>10 <h1>Hello</h1>11 <Fruit fav='banana' />12 </div>);13}14
15export 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를 추가해 보자. 그리고 수정한 파일을 저장.
1import React from 'react';2
3function Fruit() {4 return <h1>I like orange</h1>;5}6
7function App() {8 return (9 <div>10 <h1>Hello</h1>11 <Fruit fav='banana' something={true} papapapa={['hello', 1, 2, 3, 4, true]} />12 </div>);13}14
15export 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를 출력해 보자.
1const Fruit = (props) => {2 console.log(props);3 return <h1>I like orange</h1>;4};

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