[국비지원교육] [패스트캠퍼스] React 강의 7주차 (2) - React 원리
[Javascript] React
- 함수 컴포넌트
- 클래스 컴포넌트
- virtual DOM
- 마법의 hook 원리와 제약
1. 함수 컴포넌트
[app.js]
/* @jsx createElement */
import { createDOM, createElement, render } from './react'
function Title(props){
return <h1>{props.children}</h1>
}
function Item(props){
return <li style={`color: ${props.color}`}>{props.children}</li>
}
const vdom = <p>
<Title label="React">React 정말 잘 만들기</Title>
<ul>
<Item color="red">첫 번째 아이템</Item>
<Item color="blue">두 번째 아이템</Item>
<Item color="green">세 번째 아이템</Item>
</ul>
</p>
render(vdom, document.querySelector('#root'))
[react.js]
export function createDOM(vdom){
if(typeof vdom === 'string') {
return document.createTextNode(vdom);
}
const element = document.createElement(vdom.tag);
Object.entries(vdom.props)
.forEach(([name, value]) => element.setAttribute(name, value));
vdom.children
.map(createDOM)
.forEach(element.appendChild.bind(element));
return element;
}
export function createElement(tag, props, ...children){
props = props || {};
if(typeof tag === 'function'){
if(children.length > 0){
return tag({
...props,
children: children.length === 1 ? children[0] : children
})
} else {
return tag(props);
}
} else {
return { tag, props, children }
}
}
export function render(vdom, container){
container.appendChild(createDOM(vdom));
}
2. 클래스 컴포넌트
[app.js]
/* @jsx createElement */
import { createElement, render, Component } from './react';
class Title extends Component {
render(){
return <h1>{ this.props.children }</h1>
}
}
function Item(props){
return <li style={`color: ${props.color}`}>{props.children}</li>
}
const App = () => <p>
<Title label="React">React 정말 클래스 컴포넌트 잘 만들기</Title>
<ul>
<Item color="red">첫 번째 아이템</Item>
<Item color="blue">두 번째 아이템</Item>
<Item color="green">세 번째 아이템</Item>
</ul>
</p>
render(<App />, document.querySelector('#root'))
[react.js]
export class Component {
constructor(props){
this.props = props;
}
}
export function createDOM(vdom){
if(typeof vdom === 'string') {
return document.createTextNode(vdom);
}
const element = document.createElement(vdom.tag);
Object.entries(vdom.props)
.forEach(([name, value]) => element.setAttribute(name, value));
vdom.children
.map(createDOM)
.forEach(element.appendChild.bind(element));
return element;
}
function makeProps(props, children){
return {
...props,
children: children.length === 1 ? children[0] : children
}
}
export function createElement(tag, props, ...children){
props = props || {};
if(typeof tag === 'function'){
if(tag.prototype instanceof Component){
const instance = new tag(makeProps(props, children))
return instance.render();
} else {
if(children.length > 0){
return tag(makeProps(props, children));
} else {
return tag(props);
}
}
} else {
return { tag, props, children }
}
}
export function render(vdom, container){
container.appendChild(createDOM(vdom));
}
3.virtual DOM
[app.js]
export function render(vdom, container){
container.appendChild(createDOM(vdom));
}
==>
export const render = (function(){
let prevDom = null;
return function(vdom, container) {
if(prevDom === null){
prevDom = vdom;
}
//diff
container.appendChild(createDOM(vdom));
}
})();
4. 마법의 hook 원리와 제약
[app.js]
/* @jsx createElement */
import { createElement, render, Component } from './react';
class Title extends Component {
render(){
return <h1>{ this.props.children }</h1>
}
}
function Item(props){
return <li style={`color: ${props.color}`}>{props.children}</li>
}
const App = () => <p>
<Title label="React">React 정말 클래스 컴포넌트 잘 만들기</Title>
<ul>
<Item color="red">첫 번째 아이템</Item>
<Item color="blue">두 번째 아이템</Item>
<Item color="green">세 번째 아이템</Item>
</ul>
</p>
render(<App />, document.querySelector('#root'))
console.log(<App />);
[react.js]
const hooks = [];
let currentComponet = 0;
export class Component {
constructor(props){
this.props = props;
}
}
export function createDOM(vdom){
if(typeof vdom === 'string') {
return document.createTextNode(vdom);
}
const element = document.createElement(vdom.tag);
Object.entries(vdom.props)
.forEach(([name, value]) => element.setAttribute(name, value));
vdom.children
.map(createDOM)
.forEach(element.appendChild.bind(element));
return element;
}
function makeProps(props, children){
return {
...props,
children: children.length === 1 ? children[0] : children
}
}
function useState(initValue) {
let position = currentComponet - 1;
if(!hooks[position]) {
hooks[position] = initValue;
}
const modifier = nextValue => {
hooks[position] = nextValue;
};
return [ hooks[position], modifier ];
}
export function createElement(tag, props, ...children){
props = props || {};
if(typeof tag === 'function'){
if(tag.prototype instanceof Component){
const instance = new tag(makeProps(props, children))
return instance.render();
}
hooks[currentComponet] = null;
currentComponet++;
if(children.length > 0){
return tag(makeProps(props, children));
} else {
return tag(props);
}
} else {
return { tag, props, children }
}
}
export function render(vdom, container){
container.appendChild(createDOM(vdom));
}
[참고사이트]
1) awesomeopensource -.virtual DOM
https://awesomeopensource.com/
2) snabbdom -.virtual DOM
https://github.com/snabbdom/snabbdom
3) react hook
https://ko.reactjs.org/docs/hooks-intro.html
4) react native
5) next.js
6) 리액트 어플리케이션 구조 - 아토믹 디자인
https://ui.toast.com/weekly-pick/ko_20200213
'스터디 > React' 카테고리의 다른 글
[React] 강의 8주차 (1) - React _ Redux 만들기 (0) | 2023.01.13 |
---|---|
[React] 강의 7주차 (1) - React 구현 전 확인사항 (0) | 2022.12.07 |
[React] 강의 6주차 (3) -JS 데이터 (Javascript) (0) | 2022.12.07 |
[React] 강의 6주차 (2) -JS 데이터 (Javascript) (0) | 2022.11.27 |
[React] 강의 6주차 (1) -JS 데이터 (Javascript) (0) | 2022.11.17 |