이 시리즈의 이전 글은 아래로...
TIP) 간단하게 알아보는 용어
- SPA (Single Page Application): 하나의 html만을 이용하여 렌더링하는 패러다임
- CSR (Client Side Rendering): 브라우저에서 자바스크립트를 이용하여 렌더링을 하는 렌더링 방식
- Flux 패턴: 한 방향의 데이터 흐름을 갖는 디자인 패턴 (상위 -> 하위)
// index.js
const divEl = document.createElement('div');
위와 같이 자바스크립트에서 Element를 만들기만 하면 우리 브라우저는 이 Element의 존재를 모른다..!
html 태그 안에 넣어주지 않으면 그저 메모리 속에 저장되어 있다가 사라질뿐...!
// index.html
<div id="App"></div>
// index.js
const appEl = document.querySelector('#app');
// 1. 만들기
const divEl = document.createElement('div');
// 2. 화면에 표시할 수 있게 넣어주기
appEl.appendChild(divEl)
자바스크립트로 열심히 그려준 Element는 html 태그로 넣어주어야지만 실제로 화면에 보여지게 된다!
완성본은 요기!
// index.html
<div id="App"></div>
Entry Point
: 자바스크립트로 열심히 그린 Element들을 넣어주는 데에 이용이 되는 시작점
// App.js
function App({ node }) {
const initalState = {
count: 0,
onClick: () => {
const { count } = this.state
this.setState({
...this.state,
count: count + 1
});
}
};
this.state = initalState
this.setState = newState => {
this.state = {
...this.state,
...newState
}
}
};
new App({ node: appEl });
상태의 흐름과 구조는 위와 같이 간단하다!
자체적으로 상태를 가지고 있고 하위에서 변경이 발생하면 하위에서 변경하는 것이 아니라 상위로 이벤트를 올려주어 상위에서 다시 하위로 갈 수 있게 하는 것!
Q. 상위로 전달하지 않고 하위에서 상태를 바로 변경하면 안될까..?
A. 바꿀 수 있지만 하위 컴포넌트가 복잡해지는 경우, 상태 관리가 어려워짐
=> 서로 다른 상태를 렌더링해주는 문제 발생할 수 있다!
function TitleEl({ node, initalState }) {
this.state = initalState;
const h1El = document.createElement('h1');
this.setState = newState => {
this.state = {
...this.state,
...newState
}
this.render();
}
this.render = () => {
h1El.textContent = `Count: ${this.state.count}`;
}
this.init = () => {
node.appendChild(h1El);
this.render();
}
this.init();
}
Title 컴포넌트는 h1 태그를 만들고 그 안에 현재 Count를 보여주는 컴포넌트이다!
=> 상태가 변경될 때마다 변경되는 상태를 보여주면 끝!
createElement
로 그린다.setState()
: 상태가 변경되면 자신의 상태 변경과 함께 다시 렌더링을 진행한다.render()
: 변경된 상태를 반영하여 textContent를 바꾼다.init()
: 부모 컴포넌트에 createElement
로 만든 요소를 넣고 초기 렌더링을 진행한다.function ButtonEl({ node, initalState }) {
this.state = initalState;
this.init = () => {
const btnEl = document.createElement('button');
btnEl.textContent = `Count + 1`;
btnEl.addEventListener('click', () => {
this.state.onClick();
});
node.appendChild(btnEl);
}
this.init();
}
Button 컴포넌트는 button 태그를 만들고 클릭 시, 현재 Count 값에 + 1을 하게 해주는 컴포넌트이다.
=> 클릭할 때마다 전달받은 onClick을 실행시켜주면 끝!
init()
: button 엘리먼트 만들고 click 이벤트를 바인딩한 뒤, 초기 렌더링을 진행한다.잘 만들어진 하위 컴포넌트들을 연결해보쟈!
function App({ node }) {
const initalState = {
count: 0,
onClick: () => {
const { count } = this.state
this.setState({
...this.state,
count: count + 1
});
}
};
this.state = initalState
this.setState = newState => {
this.state = {
...this.state,
...newState
}
TitleComponent.setState(newState); // TitleComponent의 상태도 같이 변경
}
// 하위 컴포넌트들 생성
const ButtonComponent = new ButtonEl({ node, initalState });
const TitleComponent = new TitleEl({ node, initalState });
};
new App({ node: appEl });
setState()
: App 컴포넌트의 상태가 변경이 되었을 때, Title 컴포넌트의 상태도 같이 변경init()
메서드를 호출이유와 동작하는 형태에 대해 알아보았으니, 다음 편은 바로 TypeScript 환경 세팅 후 프로젝트 시쟉!!!