리액트에 컴포넌트를 만드는 방법은 두가지가 있다.
Class를 상속받아 만들기
class LikeButton extends Component { state = { numberOfLikes: 0, }; render(){ return <button> {this.state.numberOfLikes} </button>; } }
Function 을 이용하기
function App(){ return <h1>Hello</h1> }
컴포넌트가 state가 있고, 그 상태에 따라 컴포넌트가 주기적으로 업데이트되어야한다면 Class 컴포넌트를 쓰면 되고, 컴포넌트에 상태가 없고 정적으로 데이터가 표기된다면 Function 컴포넌트를 쓰면 된다.
즉, Class 컴포넌트에는 State를 가지고 있어서 상태가 변경이 되면 render() 함수가 자동으로 호출이 되면서 사용자에게 보여진다. 또, 상태에 따라 리액트가 사용자에게 보여주는 lifecycle methods을 사용할 수 있다.
반면에 Function 컴포넌트에는 State가 없고, lifecycle methods 도 없었다….하지만 React 16.8 버전부터 function 컴포넌트에서도 class 컴포넌트에서 할 수 있는 것처럼 할 수있는 React Hook이 도입되었다. 이를 이용하면, 함수안에서도 state, lifecycle methods를 사용할 수 있다.
class 컴포넌트를 이용하면 State와 lifecycle methods 사용을 다 할 수 있는데, 왜 굳이 함수에서 사용 할 수 있게 React Hook이 도입되었을까 ?
그 이유는 여러가지가 있다.
- 기본적으로 class는 어려움
- 클래스에서는 멤버 변수에 접근할 때 this를 붙여야함 (불편)
- 클래스에서 함수를 이용하면 바인딩 이슈가 있음
- functional programming이 유행함
- lifecycle methods 에서 중복되는 코드를 작성해야하는 경우가 있음
이제는 코드를 작성할 때 class / function 둘 중 아무거나 써도 상관이 없어졌지만, 퍼포먼스를 고려하여 사용할 줄 알아야한다.
컴포넌트 만들때 주의할 점
react 컴포넌트를 만들때 함수형태로 만든다면 함수이름은 무조건 대문자로 시작해야하고, return하는 것은 컴포넌트를 UI에 어떻게 표기할건지 명시하는 jsx 문법을 이용해야한다.
function App() { return <h1>test</h1>; } export default App;
jsx란 javascript xml의 약자로, html과 사용법이 유사하다.
여기서 주의해야할 점은 꼭 하나의 태그만 반환해야한다. 그래서 많은 경우 <div>로 감싸서 반환하곤 하는데, 만약 부모태그가 필요한 경우가 아니라면 텅빈 태그(<>)를 이용하여 감싸서 반환하면 된다.
function App() { return; <> <h1>test</h1> <h2>test22</h2> </>; } // react 내부적으로는 <Fragment> 를 사용한다. 아래 코드는 위 <> 로 감싼것과 동일하다 function App() { return ( <React.Fragment> <h1>test</h1> <h2>test22</h2> </React.Fragment> ); }
css의 경우 아래와 같이 인라인 스타일링으로 바로 추가할 수도 있다.
function App() { const name = 'dylan'; return ( <> <h1 className="main_title">{`hello, ${name} sir`}</h1> <ul> <li>{name} 1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> <img src="" alt="" style={{ width: "200px", height: "200px" }}></img> </> ); }
자바 스크립트 코드를 이용할때는 {} 중괄호를 이용해줘야한다.
function (함수) 이므로 안에 변수를 지정할 수 있는데, return 내부의 태그 안에서 변수에 접근하기 위해서는 중괄호를 이용해서 접근해야한다.
img 태그에서도 동일하다. style에 자바스크립트 코드를 넣을건데 객체형식으로 전달한다고 생각하면 된다. (width라는 키에 200px 문자열, height이라는 키에 200px 문자열 할당)
리액트 template 앱 생성
$ yarn create react-app template
상기와 같이 앱을 만들면 크게 public / src 로 나뉘어진다.
public 은 사용자가 한번에 받아서 컨텐츠가 변하지 않는 소스들을 담는다. src에는 동적으로 변하는 소스코드를 담는다.
이 차이점은 코드를 번들링해주는 webpack에서도 중요하게 작용한다. webpack은 빌드를 할때마다 자바스크립트에 유니크한 버전을 할당하는데, 사용자가 이미 웹어플리케이션을 다운로드 받았다면 자바스크립트에 변경이 없는한 이전에 할당한 고유한 번호로 캐싱처리한다. (새로 다운로드를 받지 않아도 됨)
새로운 react app 생성 후 클리닝 작업
지워도 무방한 것들은 지우자
- PWA 를 위한 파일들
- service workers
- manifest ..
처음 생성시 컴포넌트가 App.js로 생성되는데 보통 컴포넌트는 소문자로 시작하는 경우가 많으므로, app.jsx 로 변경해주자. (jsx 로 변경해주어야 리액트 컴포넌트 라는 걸 쉽게 알 수있고, js 로직을 담은 js와 쉽게 구분이 되기 때문임)
react-dom 이란?
사용자에게 궁극적으로 보여지는 페이지는 /public/index.html 이다. 해당 파일의 body에 보면 <div id=”root”></div> 가 있는데, 여기에 우리가 작성하는 자바스크립트들을 연결해주는데, 이것을 가능하게 해주는게 react-dom이다.
/src/index.js import React from "react"; import ReactDOM from "react-dom/client"; import "./index.css"; import App from "./app"; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <React.StrictMode> <App /> </React.StrictMode> ); // id root태그에 제일 최상위의 App 컴포넌트를 연결함
id root에 최상위 컴포넌트인 App이 연결되었고, app.jsx에서 return한 태그가 추가된 것을 확인할 수 있다.