JSX(JavaScript XML)는 JavaSript 코드에 XML을 추가한 확장한 문법이다. JSX는 React 프로젝트를 개발할 때 사용되므로 우리가 사용했던 공식적인 JavaScipt 문법은 아니다. JSX를 쉽게 설명하자면 HTML 태그를 변수로 할당, 호출, 반환 할 수 있는 확장문법이라고 보면 된다.
Babel 의 원래이름 6to5
를 들으면 이 녀석이 뭐하는 놈인지 짐작이 갈 것이다. '6에서5' 라는 이름을 가지고 있던 Bable
은 ES6 를 ES5로 바꿔준다는 것을 뜻한다. 2015년에 ES6가 출시되고 Chrome, Firefox 등의 브라우저는 2017년이 돼서야 ES6 지원을 시작했다. 그러다 보니 ES6를 ES5로 바꿔주는 도구가 있어야만 아직 최신 방식을 채택하지 않은 브라우저에서도 사용이 가능했다.
👨👨👦👦React와 JSX와 Babel의 관계
React는 JSX와 Babel이 없었다면 출시조차 못했을 수 있다. JSX와 Babel이 없었다면 React 를 쓰는것은 매우 어렵거나 아니면 세상에 못나왔을 수 도 있다.
React는 사용자 인터페이스를 구축하기 위한 선언적이고 효율적이며 유연한 JavaScript 라이브러리다. 컴포넌트
라고 불리는 작고 고립된 코드의 파편을 이용하여 복잡한 UI를 구성하도록 돕는다. 그럼 컴포넌트의 예시를 코드를 통해 알아보자.
다음 코드에서 보았듯이 컴포넌트의 선언은 함수형식으로 하고, 첫 글자는 꼭 대문자로 해야한다. 왜냐하면 react 에서 코드들이 랜더링이 될 때 첫 글자가 소문자로 시작하는 태그는 react 가 html 코드로 인식을 해버리기 때문이다.
index.js 는 react 에서 최초의 react
, react-dom
이라는 모듈을 로드하고 있고, 이게 우리가 브라우저의 우리의 코드를 보여주게 하는 본체라고 할 수 있다. 그럼 index.js 를 코드를 통해 알아보자
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import App from "./App";
const rootElement = document.getElementById("root");
const root = createRoot(rootElement);
root.render(
<StrictMode>
<App />
</StrictMode>
);
다음 코드에서 root.render()
에 인수에는 App.js
로 정의하고 있는 App
컴포넌트를 지정하고 있다. root.render()
를 통해 root
안에 있는 컴포넌트가 랜더링 되어 출력되는 것을 볼 수 있을 것이다.
이제 부모 컴포넌트에서 자식 컴포넌트에게 값을 전달하는 방법을 알아보자. 우리가 React 에서 자식 컴포넌트에게 값을 넘겨줄 때는 Properties
, 줄여서 Props
라는 문법을 사용한다. Props
가 다른 컴포넌트에 값을 넘겨줄 때, 부모 컴포넌트에서 자식 컴포넌트로 값을 주는 것은 가능하지만, 자식 컴포넌트에서 부모 컴포넌트에는 값을 넘겨줄 수 없는 단방향 데이터의 흐름을 가지고 있다. 또한 자식 컴포넌트는 넘겨받은 Props 값을 수정할 수 없다. 이제 코드를 통해 Props
를 사용하는 방법을 알아보자.
App.js
import Test from './Test'; function App() { const date = new Date; let pandan; if (date.getTime() <= 12) pandan = "Good Morning" else if (date.getTime() <= 17) pandan = "Good Evening" else pandan = "Good Afternoon" return ( <> <Test name={"Eddie Nketiah"} team={"Arsenal"} position = {"FW"} /> <Test name={"Mikel Arteta"} team={"Arsenal"} position = {"Coach"} /> <Test name={"Arsène Wenger"} team={"FIFA"} position = {"Director"} /> </> ); }
props
를 사용하는 방법은 부모 컴포넌트에서 자식컴포넌트가 사용되는 곳에 자신이 넘길props
의 이름을 작명해주고 그 안에 넘겨주고 싶은 값을 넣으면 된다. 그럼 자식 컴포넌트에서 부모에게 넘겨받은props
를 사용하는 방법을 알아보자.
test.jsexport default function Test(props){ return( <div> <h1>Hello, I'm {props.name}</h1> <p>I belong to {props.team}</p> <p>My position is {props.position}</p> </div> ) }
자식 컴포넌트에서 물려받은
props
를 사용하는 방법은 자식 컴포넌트 함수의 매개변수로 props를 적어주고(이름은 마음대로 적어도 가능하지만 대게 props 로 사용)내가 받아온 값을 사용할 자리에props.{넘겨준 props 이름}
을 사용하면 된다. 따라서 다음코드의 실행결과는 다음과 같다.
조건부 랜더링은 말 그대로 어떠한 조건에 따라 선택적으로 요소를 랜더링 한다는 뜻이다. 좀 전에 알아보았던 props
문법을 사용한 코드를 통해 바로 알아보자.
App.js
import Test from './Test'; function App() { return ( <> <Test name={"Eddie Nketiah"} team={"Arsenal"} position = {"FW"} champion = {true} /> <Test name={"Mikel Arteta"} team={"Arsenal"} position = {"Coach"} /> <Test name={"Arsène Wenger"} team={"FIFA"} position = {"Director"} /> </> );
Test.js
export default function Test(props){ return( <div> {props.champion && <h1>It's True</h1>} </div> ) }
Test.js
에서 {props.champion && <h1>It's True</h1>}
문을 해석하자면 props.champion
이 True
라면 뒤에 JSX 코드를 랜더링 시키고 False
라면 랜더링을 하지 않겠다는 간단한 조건문이다.
useState
를 배우기 전 먼저 state 라는 개념에 대해 알아보자. state는 간단히 말하면 변수와 비슷하다. state는 일반 변수와 다르게 값이 변하게 되면 렌더링이 발생한다. 그럼 코드를 통해 useState()를 사용하는 법을 알아보자.
import { useState } from 'react'; function Example() { const [count, setCount] = useState(0); return ( <div> <p>니가 {count} 번 눌렀음.</p> <button onClick={() => setCount(count + 1)}>클릭하셈</button> </div> ); }
다음 코드에서 먼저 useState
를 임포트했다. 그리고 const [count, setCount] = useState(0);
줄이 useState 를 선언한 곳이다. useState()
의 ()
에 쓰고싶은 자료형의 형태를 적으면 된다.(object, string, bool 등...)
useState
는 유동적이지 않은 데이터를 저장할 때 주로 사용된다. useState
를 사용하는 이유를 몇가지로 정리해보자.
- 간단하고 직관적인 사용법을 제공해 상태 관리를 쉽게 할 수 있다.
- 객체나 배열과 같은 복잡한 상태를 관리할 수 있다.
- 자동 재렌더링이 되어, state 데이터들이 변경되면 HTML에도 자동적으로 변경사항이 반영된다.
- 새로고침 없이도 DOM의 요소를 변경시켜 보여 주는 웹/앱 사이트를 만들 수 있다.