createElement 를 이용해 엘리먼트를 정의하면 복잡하기도 하고 가독성도 좋지 않다.
그래서 리액트 팀은 Element 를 정의하는 간편한 방법으로 jsx 문법을 제공한다.
자바스크립트를 확장한 문법으로 ReactElement 를 xml 문법으로 정의할 수 있는 문법이다.
단, jsx 는 공식적인 자바스크립트 문법이 아니기 때문에 바벨 이라는 트랜싱 툴이 필요하다.
추가로 jsx 는 순수 리액트로 변환해 주는 기능이 포함되었다.
(바벨이 jsx 처리 표준으로 사용된다.)
HTMl에서 React작업 시 바벨의 적용 방법(cdn)
1. 바벨 cdn 구문을 추가한다.
2. script 태그에 type 속성에 text/babel 속성값을 추가한다.
jsx 문법 내에 중괄호를 이용하여 모든 javascript 표현식을 넣을 수 있다.
<script type="text/babel">
function formatName(user){
return `${user.name} ${user.firstName}`;
}
const user = {
name : "gildong",
firstName : "Hong"
};
const element = <h1>hello, {formatName(user)}</h1>;
ReactDOM.createRoot(document.getElementById("root")).render(element);
</script>
jsx 는 편리하지만 몇가지 규칙을 준수해야한다.
동일한 레벨의 노드들이 연달아 정의되는 경우 문법적인 에러가 발생하게 된다.
여러 형제 레벨의 엘리먼트를 정의해야 하는 경우 하나의 부모 엘리먼트 (div 와 같은)로 감싸야 하는데,
div 같은 실질적인 요소를 사용하지 않으려면 fragment 를 이용할 수 있다.
<script type="text/babel">
const user = {
name : "gildong",
phone : "010-1234-5678"
};
// 1. 최상위 엘리먼트가 두 개 이상이면 에러가 발생한다. (하나의 돔 트리)
/* const element = (
<h1>hello</h1>
<h3>phone</h3>
); */
// 2. div 태그로 감싸서 하나의 돔 트리를 생성할 수 있다.
const element2 = (
<div>
<h1>hello {user.name}</h1>
<h3>phone : {user.phone}</h3>
</div>
);
// 3. <React.Fragment> 로 감싸서 형식상의 상위 엘리먼트를 만들어준다..
const element3 = (
<React.Fragment>
<h1>hello {user.name}</h1>
<h3>phone : {user.phone}</h3>
</React.Fragment>
);
// 4. React 라이브러리 Fragment 부분만 구조분해 할당
const {Fragment} = React;
const element4 = (
<Fragment>
<h1>hello {user.name}</h1>
<h3>phone : {user.phone}</h3>
</Fragment>
);
// 5. 축약 문법 사용 - 제일 많이 사용!!
const element5 = (
<>
<h1>hello {user.name}</h1>
<h3>phone : {user.phone}</h3>
</>
);
// ReactDOM.createRoot(document.getElementById("root")).render(element2);
// ReactDOM.createRoot(document.getElementById("root")).render(element3); // -> 덮어쓴다.
// ReactDOM.createRoot(document.getElementById("root")).render(element4); // -> 덮어쓴다.
ReactDOM.createRoot(document.getElementById("root")).render(element5); // -> 덮어쓴다.
</script>
JSX 를 이용해 엘리먼트를 정의할 시 attribute 도 정의할 수 있다.
주의할 사항은 class 속성은 className 이라는 속성으로 사용해야 한다.
또한 이벤트 관련 속성은 카멜표기법이다. (onclick => onClick)
JSX 에서 속성값을 부여하는 방식은 두 가지로 나뉜다.
1. 문자열로 속성값을 정의하는 방식
2. Javascript 표현식을 이용하여 정의하는 방식
<script type="text/babel">
// 1. 문자열로 속성값을 정의하는 방법 => 이벤트는 적용 안됨.
// const element = <h1 id="title" className="highlight">Hello World</h1>; // onClick 에러
// 2. javascript 표현식 이용 방법
const id = "title";
const className = "highlight";
const element = <h1 id={id} className={className} onClick={test}>Hello World</h1>; // test() : X -> 렌더링 시에 함수가 호출되기 때문에 이름만 전달해야함.
ReactDOM.createRoot(document.getElementById("root")).render(element);
function test(){
console.log("클릭했네");
}
</script>
<script type="text/babel">
const style = {
backgroundColor : "black",
color : "white",
cursor : "pointer",
textAlign : "center",
padding: 20
};
const element = (
<>
<h1 style={style}>Hello World</h1>
<h3>inline style test</h3>
</>
);
ReactDOM.createRoot(document.getElementById("root")).render(element);
</script>
<script type="text/babel">
// 1. 인라인 속성으로 이벤트 정의
// 장점 : 직관적이다.
// 단점 : 이벤트 재사용이 불가능하다. 코드를 확인하기 불편하다.
const element = (
<>
<h1>Event Attribute</h1>
<button onClick= {() => alert("hello world")}>버튼을 눌러주세요</button>
</>
);
// 2. 이벤트 동작 시 사용할 이벤트 핸들러 정의 후 jsx 내에 표현식으로 사용
// 장점 : 이벤트 재사용이 가능하다.
// 단점 : 이벤트가 많은 경우 찾기 어렵다.
const onClickHandler = () => {
alert("hello world");
}
const element2 = (
<>
<h1>Event Attribute</h1>
<button onClick= {onClickHandler}>버튼을 눌러주세요</button>
</>
);
ReactDOM.createRoot(document.getElementById("root")).render(element2);
</script>
<script type="text/babel">
// 한줄 주석
/*
자바스크립트 여러 줄 주석
*/
const element = (
<>
<h1>Comment in jsx</h1>
{/* jsx 내에서 주석은 이렇게 작성한다..*/}
{
// 한줄 주석
}
// 이런 주석이나
/* 이런 주석은 화면에 표시된다.. */
</>
);
ReactDOM.createRoot(document.getElementById("root")).render(element);
</script>