react가 어떻게 작동 알아보기 👆
index.js
구성
const list = [
{title : "react"}, {title : "redux"}, {title : "typescript"}]
//어떠한 데이터를 만들어 준뒤
const rootElement = document.getElementById("root")
//root 를 ID값으로 가지는 div요소를 가져온것을 rootElement 변수에 저장한다
function app (items) {
rootElement.innerHTML = `
<ul>
${items.map(item => `<li>${item.title}</li>`.join("")}
</ul>
`;
}
app(list);
결국 매번 app을 빌드하는 상황을 피하기 위해 virtual dom이라는 컨셉이 등장했다.
virtual dom사용에 관한 공식 문서
virtual dom은 프로그래밍 concept으로서 UI를 메모리에 저장하고 "real"dom 을 ReactDOM이라는 내장 라이브러리를 통해 reconcile
시키는 개념으로 볼 수 있다.
-좋은 코딩, 결국 같은 것 끼리 묶고 다른것은 분리하자는 것이 대 원칙
이다.
-어떤게 다르고, 어떤게 같은 것인지를 아는 것과 복잡도 있는 데이터를 어떻게 다루어야 하는지도 결국은 같은 것 끼리 묶고 다른 것 끼리 분리한다는 것이 중심이다
그렇다면? 다루기 쉬운 구조로 만들어서 연결해서 다루어야 하는데..
브라우저는 html태그 문자열로 그려져 있고, DOM에 JS가 virtual DOM만 접근해서 virtual dom이 알아서 하는 구조로 만들고 virtualDOM과 js의 쉬운 형태를 유지 해 주는 것 그것이 목표이니 간단하게 만들어 보자
function StudyList() {
return (
<ul>
<li className="item">react</li>
<li className="item">redux</li>
<li className="item">typescript</li>
<li className="item">mobx</li>
</ul>
);
}
// 까다로운 문자열을 virtual dom 형태로 표현해 보자
const vdom = {
type: "ul",
props: {},
children : [
{ type: "li", props: { className: "item" }, children: "React" },
{ type: "li", props: { className: "item" }, children: "Redux" },
{ type: "li", props: { className: "item" }, children: "Typescript" },
{ type: "li", props: { className: "item" }, children: "MobX" },
]
};
// 목록을 출력하는 용도의 태그 컴포넌트들
// 관련된 이름을 정해주어야 한다.(읽기 쉬운 코드가 고치기도 쉽다)
// 실제로는 함수를 호출하는 형테(바벨에서 컴파일해서 나오는것)
// real dom으로 converting 하는 형태
해당 vdom을 리액트로 구현해 보면
React.createElement
function createElement(type, props = {}, ...children) {
return { type, props, children };
}
const vdom = createElement("ul", {}, createElement("li", {}, "React"));
// creatElement를 통해 객체를 만들어 주는 이 함수 이후 객체를 붙인다. real dom으로 컨버팅 하는 요소이다.
function renderElement (node) {
if(typeof node == "string") {
return document.createTextNode(node);
}
if(node === undefined) return;
const $el = document.createElement(node.type);
//Html element 를 표현하는 변수명 컨벤션으로 $ 를 많이 사용함
node.children.map(renderElement).forEach(node => {$el.appendChild(node);})
return $el;
}
//전형적인 재귀호출
function render(newvdom,container) {
let vdom;
//vdom vs newvdom 실제는 이런 비교 로직이 들어간다
container.appendchild(renderElement(vdom))
}
function createElement(type,props={}, ...children) {
//바벨이 compile 하는것을 코드로 보여주는 것
if(typeof type === "function") {
return type.apply(null,[props, ...children])}
return {type, props, children}
}
const vdom = createElement("ul", {}, createElement("li",{},"React");
console.log(<App /> )
//을 찍어보면 객체 형태가 나온다
const app = <App />
//var app = H (App, null) 로 컴파일 된다 .
```
built-in component와 렌더링 컴포넌트를 대소문자로 구분하는 이유 이고, 그래서 리액트 컴포넌트는 대문자로 시작해 주어야 한다.
### 리액트의 기본기 알아보기
- 리액트는 함수형과 클래스형 컴포넌트가 있는데, 클래스컴포넌트는 Lifecycle API로 상태관리를 할 수 있고, 함수형 또한 hooks를 통해 상태관리가 가능하다.
```jsx
// 클래스 형 예시
class Hello extends React.Component {
constructor(props) {
super(props);
}
this.state ={
count: 1}
componentDidMount() {
this.setState({count = this.state.count+1 });
}
render()
{
return (
<p>hi</p>)
}
}
// 함수형 예시
function App() {
const [counter, setCounter] =useState(1)
return (
<div>
<h1 onclick = {() => setCounter(counter +1)}>상태 {counter}</h1>
<Hello />
</div>
//최상위 객체가 두개 있을 수 없어서 묶어 주어야 한다.
);
}
ReactDOM.render(<App />, document.getElementById("root"))