JS 함수 컨포넌트
리액트가 사용자 컴포넌트를 만드는 방법
- 함수로 컴포넌트 만드는 방법
- 클래스로 컴포넌트 만드는 방법
사용자 컴포넌트를 만들게 되면 HTML 태그와 같은 것으로만 마크업을 하는 것과 정말 다르게 UI조각을 JS 모듈화 하듯이 조직화할 수 있음
모듈화 할 수 있다는 것은 언제든 필요할 때 재활용할 수 있고 사용자가 이름을 붙여서 HTML 태그와는 다르게 훨씬 더 의미가 명확한 형태로 UI를 만들 수 있는 장점이 생김
function Title(){
return <h1>React 만들기</h1>;
}
<Title></Title>
사용자 컴포넌트를 만들어서 이름을 부여하고 이름이 잘 명명된다면 UI 구성을 훨씬 더 readability(읽기 쉬운) 높일 수 있는 장점이 생김


Jsx문법에 태그의 이름이 대문자로 시작되면 문자열로 취급하지 않고 JS값으로 취급함
그 값은 반드시 함수여야 하고 그 함수는 Jsx를 리턴하는 즉 그 안에서 리턴되는 것은 createElment의 리턴결과 값이어야 한다는 내부적 약속을 갖고 있고 그렇게 동작되도록 디자인되어있음
function Title(props) {
//컴포넌트가 바깥쪽에서 props를 데이터로 주입받아서 활용
return <h1>{props.children}</h1>;
}
function Item(props) {
return <li style={`color:${props.color}`}>{props.children}</li>;
}
const vdom4 = (
//사용자 컴포넌트를 이용해서 만들기
<p>
<Title>React 잘 만들기</Title>
<ul>
<Item color="red">첫번째 아이템</Item>
<Item color="crimson">두번째 아이템</Item>
<Item color="orange">세번째 아이템</Item>
</ul>
</p>
);
export function createEl(tag, props, ...children) {
props = props || {}; //undefined나 null이 들어왔을 경우를 위한 방어코드
if (typeof tag === "function") {
if (children.length > 0) {
return tag({
...props,
children: children.length === 1 ? children[0] : children,
});
} else {
return tag(props);
}
} else {
return {
//가변인자 children 배열이됨
tag, //이름이 변수와 같으니 생략가능 tag: tag
props,
children,
};
}
}
사용자 컴포넌트 식으로 변경된 코드
JS 클래스 컴포넌트
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>React 클래스 컴포넌트 잘 만들기</Title>
<ul>
<Item color="red">첫번째 아이템</Item>
<Item color="blue">두번째 아이템</Item>
<Item color="green">세번째 아이템</Item>
</ul>
</p>
);
render(<App />, document.querySelector("#root"));
function makeProps(props, children) {
return {
...props,
children: children.length === 1 ? children[0] : children,
};
}
export function createEl(tag, props, ...children) {
props = props || {}; //undefined나 null이 들어왔을 경우를 위한 방어코드
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 {
//가변인자 children 배열이됨
tag, //이름이 변수와 같으니 생략가능 tag: tag
props,
children,
};
}
}
리렌더의 문제로 실제로 이렇게 구현되어 있는 것은 아님
최초로 생성되는 컴포넌트는 인스턴스를 만들고 그다음부터 업데이트함
클래스 컴포넌트 인스턴스가 DOM에 실제로 Mount 되고 안착돼서 렌더링 돼서 화면에 보인 이후에 완전히 사라지는 컴포넌트가 삭제된 이후에는 다시 렌더링 된다고 하면 인스턴스에서 만들고 그 사이에서는 new 인스턴스를 만드는 것이 아니라 이미 만들어진 인스턴스를 가지고 계속 render만 호출하는 식으로 되어있음
내부적으로 인스턴스 안에 Context의 상태가 계속 유지되기 때문
내부적으로 함수가 즉시 호출되는 것과는 달리 클래스 컴포넌트는 인스턴스를 만들고 인스턴스를 컴포넌트가 삭제될 때까지 계속 유지하면서 render함수를 호출하는 식으로 작동되게끔 디자인되어있음
그래서 함수컴포넌트는 상태를 가질 수 없고 클래스 컴포넌트는 상태를 가질 수 있음
함수컴포넌트는 상태를 가질 수 없었음. 호출될 때마다 늘 똑같은 상태, 모든 것이 초기화된 상태이기 때문
그것이 바로 함수 컴포넌트의 단점이었지만 Hook이라는 기능을 React가 제공하면서 함수 컴포넌트도 상태를 가질 수 있는 상황이 됨
그러면서 상황이 발전되 라이클 사이클 메서드나 인스턴스를 만들어서 여러 가지를 신경 써야 했던 번거로운 클래스 컴포넌트보다 최근에 React커뮤니티에 흐름은 함수컴포넌트로 넘어갔음
JS Virtual DOM
DOM을 직접적으로 제어하지 않고 애플리케이션 개발자들이 DOM보다 훨씬 더 쉬운 구조물을 만들고 UI를 개발할 수 있게끔 중간의 DOM처리는 React한테 맡기고 개발자들한테는 Jsx라고 하는 마치 DOM과 비슷한 HTML태그와 비슷한 컴포넌트의 개발방식을 만들어줄 수 있게 만드는 환경이 바로 Virtual DOM이라고 할 수 있음
export const render = (function () {
//업데이트할때마다 비교해서 이전과 비교하여 업데이트 된 부분은 업데이트
let prevDom = null;
return function (vdom, container) {
if (prevDom === null) {
prevDom = vdom;
}
//diff
container.appendChild(createDom(vdom));
};
})();
마법의 hook 원리와 제약
Hook: 함수가 상태를 가질 수 있게 만들어 주는 기능
https://reactjs.org/docs/hooks-intro.html
Introducing Hooks – React
A JavaScript library for building user interfaces
reactjs.org
기존의 react는 컴포넌트가 상태를 가질려면 클래스컴포넌트만이 상태를 가질 수 있었음
함수컴포넌트는 호출될때 마다 모든 것이 리셋되어 상태라는 것을 유지할 수 없었음
하지만 hook이 생기면서 함수 컴포넌트가 상태를 가질 수 있게 됨
하지만 hook을 이용하는데 몇가지 제약사항이 있음
오직 react 함수 내에서 hook을 호출해야 함. hook을 일반적인 JS함수에서 호출할 수 없음
hook은 react함수 컴포넌트에서 hook을 호출하거나 Custom Hook에서 hook을 호출할 수 있음
'기초 > 프론트엔드 종합반 HTML&CSS, JS, React' 카테고리의 다른 글
7주차_ HTML/CSS/JS로 만드는 스타벅스 웹사이트4 (0) | 2023.01.22 |
---|---|
7주차_ HTML/CSS/JS로 만드는 스타벅스 웹사이트2 (0) | 2023.01.20 |
7주차_ HTML/CSS/JS로 만드는 스타벅스 웹사이트 (0) | 2023.01.20 |
6주차_ HTML/CSS/JS로 만드는 스타벅스 웹사이트3 (0) | 2023.01.18 |
6주차_ HTML/CSS/JS로 만드는 스타벅스 웹사이트2 (0) | 2023.01.17 |
댓글