우선, JSX는 왜 JSX인가?
일단 무작정 검색해보자.
사전을 검색해보니, JSX란? JavaScript + XML을 추가해서 확장한 문법이다. XML에 대한 부분은 다른 영역에서 설명해주고 있으니, 생략하겠다. 여기서 중요한 말은 문법
이다 React를 쓸때, 보통 js파일과 jsx파일을 생성했었다. 이때 본인은 JSX가 JS처럼 어떤 언어로 생각했다. 하지만 위에서 알 수 있듯이 문법
이다. 문법? 언어? 말로만 했을때 너무 헷갈린다. 아래 참고 코드를 한번 봐보자.
function TestButton() {
const [test, setTest] = React.useState(0);
const text = test ? "성공" : "실패";
return React.createElement("button", { onClick: () => setTest(!test) }, test);
}
-----------------------------------------------------------------------------------
document.getElementById("test").onclick = function(){
this.style.fontSize = "20px"
}
----------------------------------------------------------------------------------------
기존 JS와 HTML을 연결 해주기 위해선 JS 파일에 위와 같이 코드를 짠 다음에 React.createElement()
라는 함수로 HTML태그(id,class 등등으로)와 연결해주는 방식이었다. 우리가 React에서 했던 코드랑은 확실히 다르다.
이 뿐 아니라 Vanilla JS로 구현한 아래와 같은 코드가 가능하다.
이 또한 확실히 가독성이 떨어진다. 그렇다면 JSX는 어떠한가?
순수 Javascript
로 정의할 수 있다. 쉽게 바닐라 아이스크림을 떠올려보면 뭔지 바로 알 수 있다. 모든 맛의 아이스크림은 어디서부터 나왔다고 생각하는가? 아이스크림의 기초는 아무것도 들어가지 않는 순수 바닐라 아이스크림이다.
function TestButton() {
const [test, setTest] = React.useState(0);
const text = test ? "성공" : "실패";
return (
<button onClick={()=>setTest(!test)}>
{text}
</button>
)
}
여기서 return
부분을 보면 우리가 HTML에서 쓰던 태그들이 들어가있다. 만약, 순수 JS로 이를 개발했다면 무조건 오류가 뜰 것이다.
이것이 JSX 때문에 가능한 일이다. 이 덕분에 가독성이 더 좋아진 것을 볼 수 있다. JSX를 개발한 이유가 이 때문이다. UI를 만들때 JS와 따로 만드는 것이 아니라, 같은 부분에서 HTML과 JS가 함께 있으면 코드 짜기에도 편하고 가독성 또한 올라간다. 위에 코드로 JSX가 뭔지 맛만 봐봤다. JSX는 정확히 무엇이며, 이것이 어떻게 가능할까?
JSX에 대해 간단히 요약하면 , 위에 코드에서 알 수 있듯이 JavaScript
안에서 HTML
을 사용 가능하게 한 문법이다.
→JSX를 설명하고 있는 갑자기 Virtual Dom
? 당황스러울 수 있다. 하지만 아래 개념을 봐보자.
이를 요약하면, 기존 DOM을 가볍게 만든 JavaScript표현이다.
HTML코드를 읽는 파싱
이라는 과정이 있는데, 이때 HTML 코드를 트리형태로 구조화 시켜서 저장한다. 이때 사용하는 것이 DOM
이다. 이렇게 저장을 해놓고, getElementbyid
같은 함수로 이 구조에 접근하는 방식을 취했다.
기존 DOM은 새로운 element가 업데이트 되면 전제 다를 바꿔서 시간도 오래 걸리고, 메모리 낭비가 심했다. 이를 해결하기 위해 나온것이 Virtual DOM이다.
→ Virtual Dom의 장점은 하나가 바뀌면 전체를 바꾸지 않고, 그 부분만 바꿨다. 이 덕분에 기존의 DOM의 문제를 해결할 수 있었다.
하지만 이에도 문제가 있었다. 아래 코드를 봐보자.
예시를 하나 들어보겠다.
<div id="app">
<ul>
<li>
<input type="checkbox" class="toggle" />
todo list item 1
<button class="remove">삭제</button>
</li>
</ul>
</div>
//virtual Dom 구조 표현 방식
function h(type, props, ...children) { /* 중간 생략 */ }
function createElement(node) { /* 중간 생략 */ }
createElement(
h('div', { id: 'app' },
h('ul', null,
h('li', null,
h('input', { type: 'checkbox', class: 'toggle' }),
'todo list item 1',
h('button', { class: 'remove' }, '삭제')
)
)
)
);
이와 같이 Virtual Dom은 기존 DOM을 객체화
시킨 것이다. 하지만 기존에 있던 DOM의 코드보다 훨씬 가독성
이 떨어진다. 이때 등장한 것이 JSX 이다.
Virtual Dom의 가독성을 높이기 위해, JSX는 기존 HTML 태그를 개발자들이 볼 수 있게 문법으로 정했다. 위에 코드를 JSX 형식으로 바꾼다면 아래와 같다.
function h(type, props, ...children) { /* 중간 생략 */ }
function createElement(node) { /* 중간 생략 */ }
createElement(
<div id="app">
<ul>
<li>
<input type="checkbox" class="toggle" />
todo list item 1
<button class="remove">삭제</button>
</li>
</ul>
</div>
);
훨씬 가독성이 좋아진것을 확인할 수 있다.
지금까지 말한게 조금 이해가 어려울 수 있는데, 아래 순서도를 확인해보자.
DOM
Virtual DOM
JSX
이러한 과정들을 겪으면서 JSX가 생긴것이다.
한마디로 JSX는 virtual Dom의 가독성을 높이기 위한 문법
이라고 하는 것이 정확하다. 그래서 JSX가 JS + XML 인것이다.
가독성을 높이기 위해 HTML와 유사한 태그들을 사용하게 한 것이고, 이 때문에 JS에서 HTML 합쳤다는 말이 나오는 것이다.
들어가기 전에 아래와 같이 변수 선언을 해보자.
const element = <h1>Hello, world!</h1>
이 코드는 React에서 JSX 이해를 돕기 위해 활용한 예시 코드이다. 이를 해석하자면, 변수를 하나 선언하는데 식별자는 element
이며 데이터는 <h1>Hello, world!</h1>
로 할당했다. 이것이 가능할까? 기존 JS만을 가지고 한다면 이는 불가능하다.
하지만 우리가 VS code에 이를 입력해보자. 오류가 뜨지 않을 것이다.
이것이 가능한 이유가 JSX문법이 있기 때문이다. JSX는 자바스크립트의 문법 확장판이다. 이는 하나의 변수에 HTML 태그들을 할당할 수 있다. 당연하게도 이를 가지고 호출하고 리턴하고 다 할 수 있다. 이는 앞써 설명한 것처럼 Virtual Dom 구조 덕분에 객체로 받아들이기 때문이다.
본인은 React에서 JS파일에 HTML 태그들을 아무렇지도 않게 Return 하고 변수에 할당했었다. JS는 당연하게 HTML을 사용이 가능한 줄 알았다. 하지만, 이는 JSX 문법 덕분이다. 아래 예시코드를 하나 더 보자.
function App() {
return (
<>
<div className="test">test</div>
</>
);
}
여기서 주목해야 될 부분은 className
이다. 이것도 하나의 JSX문법인데, HTML에서 태그에 클래스 이름을 부여할때 class = "test"
이렇게 했다. 하지만 React에서 JS파일에선 className="test"
라고 해야된다. 이를 통해 JS에 HTML문법을 사용하는 것이 아니라, 우리가 사용하는 것은 JSX문법이며, 이것이 JS에서 HTML의 기능을 사용할 수 있게끔 해주는 것이다.
이 점에서 className
이란걸 봤을때 우리는 눈치 챘어야 한다. HTML과는 다르다는 걸….
아무 의심 없이 className
을 썼던 이 부분에서 많이 반성을 하게 된 것 같다.
JSX는 어떤 방식으로 돌아갈까?
JSX 문법이 웹 브라우저에서 돌아갈 수 있게끔 하는 것이 Babel
이라고 해도 과언이 아니다. 그렇다면 도대체 Babel
이 무엇인데, 이를 가능하게 해줄까?
Babel
은 과거에 6to5라는 이름을 가졌다. 여기서 6은 ES6(ECMAScript 6)
을 의미하며, 5은 ES5(ECMAScript 5)
를 의미한다. 따라서 6세대에서 5세대로 가게 해준다는 의미이다. JS에는 모든 프로그래밍이 그렇지만, 계속된 업데이트가 있었고 여러 버전이 있었을 것이다.
이때 문제가 발생하는데, 여러 브라우저(ex. Chrome, Edge, FireFox…등등) 에서 업데이트 된 최신 문법(ex. JSX
) 들을 호환하지 못하면, 오래된 브라우저는 사용을 못한다는 문제가 있었다. 아래 사진은 ES6을 호환하기 시작한 날에 대한 자료이다. 이처럼 업데이트를 따라가지 못한 브라우져에선 이를 사용하지 못한다.
이를 해결하기 위한 것이 Babel
이다. 이를 사용하면, JSX
와 같은 최신 문법을 브라우저가 일기 쉬운 ES5
코드로 변환해준다. 그래서 JSX의 문법을 사용하면, babel이 과거 문법(Virtual Dom의 형태)으로 변환 시켜주는 역할을 하며 JSX가 구동이 가능하게 한다.
그렇다면 이런 생각을 할 수 있을 것이다. 나는 Babel
이란걸 설치한적도 없는데, JSX문법이 실행되고, 웹 브라우저에서 잘만 돌아가던데??
이에 대해서 본인도 궁금증이 생겼고 조사해보니, 보통 개발을 할때 프로젝트와 리액트를 설치하게 되는데, 이때 자동적으로 Babel이 설치 되었다. 아래 사진은 연습 프로젝트 파일에 있던 Babel에 대한 정보이다. 이처럼 자동적으로 설정되어있는 것을 확인할 수 있다. 이 때문에 어떤 브라우저에서든 JSX 문법을 사용할 수 있던 것이다.
+여기서 babel/core : 기본적인 바벨로 최신 문법으로 변환해주는 역할을 한다.
이러한 Babel
덕분에 우리가 JSX문법을 사용할 수 있게 된것이다.
이제 JSX가 무엇이며, 어떻게 구동되는지 이해했다.
JSX는 보통 HTML의 코드를 쓸때, 보통 쓰던대로 쓰면 되지만, 조금씩 다른것이 있다. 마지막으로는 기존 HTML과 차별된 JSX의 대표적인 문법이 뭐가 있는지 소개하며, 마치겠다.
→ 대부분은 유사
앞서 예시로 들은 코드를 다시 한번 가져오겠다.
function App() {
return (
<>
<div className="test">test</div>
</>
);
}
여기서 주목할 점은 className
이라고 했는데, 기존 HTML에선 클래스 이름을 선언할 때 class="클래스명"
으로 하지만, 여기선 className="클래스명"
으로 선언해야 된다. 왜 그럴까? 자세히 알아보니, JS+HTML이 되면서 JS에 class라는 것이 있기 때문에 이에 대한 혼동을 없애기 위해 위와 같은 문법을 적용시켰다고 한다.
아래 코드를 참고해보자.
const name = "sean";
function App() {
return (
<>
<div className="test">{name}</div>
</>
);
}
export default App;
JS와 HTML이 합쳐지면서 JS 변수를 HTML 태그에 넣을 수 있다. 이때는 꼭 중괄호
가 필수이다. 중괄호 안에 변수명(식별자)을 넣으면 그 데이터 값을 사용할 수 있다.
이렇듯, 우리가 JS파일 혹은 JSX파일에서 component를 만들고, 이를 변수에 저장하고 호출하고 등등 이러한 행위가 모두 JSX 문법 덕분에 일어난 것이다. 아마도 본인처럼 이러한 것들을 아무 의심없이 사용하며 JSX문법이라고 생각하지 않고, 당연히 JS에서 쓸 수 있다고 생각한다. 하지만 JSX공부를 한 사람들은 이것이 JSX 덕분이란 걸 알아야한다.
이런 부분을 공부하면서 개념에 대한 프로그래밍 접근 깊이
의 차이에 대해 느낀 것 같다.
https://ko.reactjs.org/docs/introducing-jsx.html
https://goddaehee.tistory.com/296
https://stackoverflow.com/questions/46169472/reactjs-js-vs-jsx
https://domyutmost.tistory.com/18
https://junilhwang.github.io/TIL/Javascript/Design/Vanilla-JS-Virtual-DOM/#_5-%E1%84%92%E1%85%A1%E1%86%B8%E1%84%89%E1%85%A5%E1%86%BC-compositing
https://brunch.co.kr/@skykamja24/576