아래 ReactDOM이 렌더링하는 순서에 대해 구조를 이해하고, 결과값을 예측할 수 있어야 한다.
<html>
<head>
<!-- React, ReactDOM CDN 호출 -->
<script crossorigin src="<https://unpkg.com/react@17/umd/react.development.js>"></script>
<script crossorigin src="<https://unpkg.com/react-dom@17/umd/react-dom.development.js>"></script>
</head>
<body>
<div id="root"></div><!-- 결과: <div id="root"><button>Like</button></div> -->
<script>
const e = React.createElement;
// React.Component를 상속받는 LikeButton
class LikeButton extends React.Component {
// component가 실행될 때 가장 상단에 선언
constructor(props) {
super(props);
}
// <button>Like</button> 마크업을 만들겠다! (만든다가 아님)
render() {
return e("button", null, "Like");
}
}
</script>
<script>
// e(LikeButton)을 root 엘리먼트에 렌더링하겠다.
ReactDOM.render(e(LikeButton), document.querySelector("#root"));
</script>
</body>
</html>
리액트에서는 상태를 관리할 수 있다. 상태는 바뀌는 것으로 초기값을 constructor에서 설정한 뒤 setState
메서드로 상태값을 바꿔줄 수 있다.(Like → Liked)
기존에는 jQuery를 통해 셀렉터마다 직접 데이터를 주입하는 방법을 사용했지만, 서비스의 규모가 커질수록 그러한 방법은 지나치게 비효율적이므로 데이터를 상태로 관리하는 방법을 React에서 사용하므로 효율성이 증대했다.
프로그래밍 사고의 변화가 일어나는 순간이다 :)
<html>
<head>
<script crossorigin src="<https://unpkg.com/react@17/umd/react.development.js>"></script>
<script crossorigin src="<https://unpkg.com/react-dom@17/umd/react-dom.development.js>"></script>
</head>
<body>
<div id="root"></div>
<script>
const e = React.createElement;
class LikeButton extends React.Component {
constructor(props) {
super(props);
// 상태는 바뀌는 것(Like -> Liked)이며, 상태는 constructor 안에서 설정한다.
this.state = {
liked: false,
};
}
// <button onclick="() => { this.setState({ liked: true }) }" type="submit">Like</button>
render() {
return e(
"button",
{
onClick: () => {
this.setState({ liked: true }); // 상태를 바꿔준다.
},
type: "submit",
},
this.state.liked === true ? "Liked" : "Like" // 원래는 $('button').text('Liked')로 일일히 변경해야 했다.
);
}
}
</script>
<script>
// e(LikeButton)을 root 엘리먼트에 렌더링하겠다.
ReactDOM.render(e(LikeButton), document.querySelector("#root"));
</script>
</body>
</html>
위 LikeButton 컴포넌트의 render 내부를 보면 뭔가 복잡하고 난해하다. 좀 더 쉽고 직관적인 코드 작업을 위해 React에서는 태그형식으로 값을 리턴할 수 있도록 JSX(JS+XML) 문법을 제공한다.
<html>
<head>
<script crossorigin src="<https://unpkg.com/react@17/umd/react.development.js>"></script>
<script crossorigin src="<https://unpkg.com/react-dom@17/umd/react-dom.development.js>"></script>
<!-- 1. babel cdn -->
<script src="<https://unpkg.com/@babel/standalone/babel.min.js>"></script>
</head>
<body>
<div id="root"></div>
<!-- 2. script type을 babel로 지정 -->
<script type="text/babel">
class LikeButton extends React.Component {
constructor(props) {
super(props);
this.state = {
liked: false,
};
}
render() {
// 3. JSX 문법 (JS + XML)
return (
<button
type="submit"
className="" // 5. jsx 내부의 class나 for property
htmlFor=""
onClick={() => {
this.setState({ liked: true });
}}
>
// 4. 중괄호로 내부 스크립트 사용
{this.state.liked === true ? "Liked" : "Like"}
</button>
);
}
}
</script>
<!-- 2. script type을 babel로 지정 -->
<script type="text/babel">
ReactDOM.render(
<>
<LikeButton />
</>,
document.querySelector("#root")
);
</script>
</body>
</html>
<script src="<https://unpkg.com/@babel/standalone/babel.min.js>"></script>
text/babel
로 지정해야 한다.{}
를 감싸주면 그 내부에서 또 스크립트를 작성할 수 있다.className
, htmlFor
로 바꿔서 사용해야한다. (JSX문법)