
컴포넌트는 레고 조각이라고 생각하면 된다. 같은 레고 조각을 다양한 레고에 끼워 넣을 수 있듯, 컴포넌트를 통해 UI를 재사용이 가능한 개별적인 여러 조각을 나눌 수 있다.
JS 함수와 개념적으로 유사하다! prop라는 입력을 받으면 화면에 어떻게 표시되는지를 기술하는 React element를 반환한다.
// props라는 입력을 받음
// 화면에 어떻게 표현되는지를 기술하는 React 엘리먼츠를 반환(return)
function Welcome (props) {
return <h1>Hello, {props.name}</h1>;
}
// props 없어도 물론 가능
function App () {
return <div>hello</div>
}
현대 리액트에선 클래스형 보다는 함수형을 지향한다.
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
// 📁 폴더 이름은 camelCase
// jsx 파일, 컴포넌트 이름은 PascalCase
// 컴포넌트 밖
// 필요한 파일을 불러오는 영역
import React from 'react';
// 컴포넌트 안
// 컴포넌트를 작성하는 영역
function App() {
/**
<----- JS 영역 ----->
*/
return (
/**
<div>
<------ JSX 영역 ------>
</div>
*/
);
}
// 컴포넌트 밖
// 만든 컴포넌트를 내보내는 영역
export default App;
컴포넌트는 어디에나 넣을 수 있는 조각이기 때문에, 컴포넌트 안에 컴포넌트를 넣을 수도 있다! 자연스럽게 부모-자식 관계, 즉 종속성을 가지게 된다.
import React from "react";
function Child() {
return <div>Child Component</div>;
}
function App() {
return <Child />;
}
export default App;
위와 같이 <자식 컴포넌트 이름/>태그를 이용하여 컴포넌트 안에 컴포넌트를 넣을 수 있다.
JSX는 JS + XML로, React Element를 생성하기 위한 문법이다. 기본적으로 JS를 확장한 문법이기 때문에 JS의 모든 기능이 포함되어 있다.
JSX 문법을 사용하면 JS 안에서도 HTML 마크업을 사용할 수 있어 View(UI)작업을 편하게 할 수 있도록 만들어준다.
🪄React Element 와 DOM Element
React Element는 가상 DOM인 React DOM을 구성하는 요소다.
DOM Element는 실제 DOM을 구성하므로 둘은 비슷하지만 구분되어야 한다.
Q. 브라우저는 JS만 해석 할 수 있으니, JSX는 해석 못하지 않나요?
A. 그렇다. 브라우저는 JSX를 직접 해석하지 못한다. 그래서babel을 사용하여 JSX를 JS로 변환해준다!// 변환 전, 우리가 보는 JSX 파일 const element = ( <h1 className="greeting"> Hello, world! </h1> ); // 변환 후, 브라우저가 보는 JS 파일 const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' );
JS 영역에서 만든 함수나 변수를 JSX 영역에서도 사용 가능하다! {}를 사용하면 된다.
태그 속성 값 뿐만 아니라, 태그 값(<div>함수!</div>)에도 함수를 사용할 수 있다.
function App() {
const handleClick = () => {
console.log("hello!")
};
const click = 'Click!'
return (
<div>
<button onClick={handleClick}>{click}</button>
</div>
);
}
// 에러!
function App() {
return (
<div>첫 번째 요소</div> // JSX 식에는 부모 요소가 하나 있어야 함!
<div>두 번째 요소</div>
);
}
// 이런 식으로 고쳐야 한다
function App() {
return (
<div>
<div>첫 번째 요소</div>
<div>두 번째 요소</div>
</div>
);
}
// 부모 div를 사용하고 싶지 않다면?
// 아래와 같이 꺾쇠만 사용하면 내부의 값만 인식한다!
function App() {
return (
<>
<div>첫 번째 요소</div>
<div>두 번째 요소</div>
</>
);
}
className을 사용한다.function App() {
return (
<>
<div class="first">첫 번째 요소</div> // 이러면 안 되고
<div className="second">두 번째 요소</div> // 이렇게 해야한다!
</>
);
}
중괄호를 두 번 써야하는데, 특별한 문법이 아니라 평범한 문법의 결과다.
style은 객체로 지정하는데, 객체도 JS이므로 바깥 중괄호는 JS 문법을 사용하기 위한 문법, 안쪽 중괄호는 style 객체를 표현하기 위한 문법이다.
가독성이 별로일 수 있으니 변수로 따로 설정 후 사용하는 편이 더 좋다!
// 인라인 스타일
function App() {
return (
<div className="App">
<p style={{color: 'orange', fontSize: '20px'}}>orange</p>
</div>
);
}
// 스타일 객체를 변수로 만들어 사용
function App() {
const styles = {
color: 'orange',
fontSize: '20px'
};
return (
<div className="App">
<p style={styles}>orange</p>
</div>
);
}
import React from "react"JSX파일을 보면 import React from "react"; 가 최상단에 위치한 경우를 흔하게 볼 수 있다. 이것의 역할은 무엇일까?
import React from "react";는 React를 사용하는 환경에서 특정 기능들을 가져오기 위해 사용하는 구문이다. 특히 JSX 문법을 사용할 때 주로 이 구문이 필요했었다.
React.createElement():
JSX 문법이 내부적으로 변환되는 함수로, JSX를 사용할 경우 Babel이 JSX 코드를 React.createElement() 호출로 변환해준다.
React API 제공:
React는 컴포넌트 작성, 상태 관리, 렌더링 등을 위한 다양한 API를 제공한다.
useState, useEffect와 같은 훅(Hooks)React.Component 클래스 (클래스형 컴포넌트를 작성할 때 사용)React 17 이전에는 JSX가 항상 React.createElement를 필요로 했기 때문에, JSX를 사용하는 모든 파일에서 import React from "react";를 반드시 추가해야 했다.
React 17부터는 자동 JSX 변환 기능이 도입되었다. 이로 인해 JSX를 사용하는 파일에서 import React from "react";를 명시적으로 추가하지 않아도 React가 필요할 때 자동으로 임포트된다.
자동 JSX 변환이 도입된 React 17 이후에는 필수적이지는 않지만, 프로젝트에 따라 여전히 명시적으로 React를 가져오는 경우가 있긴 하다.
React 17 이후 import React from "react";는 아래와 같은 경우 여전히 필요할 수도 있다.
JSX 없이 React API를 사용하는 경우:
import React from "react";
const element = React.createElement('div', null, 'Hello, World!');
React API를 직접 호출하는 경우:
import React, { useState } from "react";
function MyComponent() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}