-
[JS/class] 클래스로 컴포넌트 구현하기 2 - 자식 컴포넌트에 데이터 전달하기조각조각/JavaScript 2024. 4. 4. 22:27
프런트엔드 웹 개발의 모든 것 초격차 패키지 Online. 강좌를 보며 새롭게 알게 된 사실들을 기록합니다.🙌
✍️ 이전 포스팅
https://dev-thinking.tistory.com/39
1. 자식 컴포넌트 생성
현재 요소 태그로 렌더링 되고 있는 <li>${fruit.name}</li> 부분을 컴포넌트화 시켜보자.
1-1. FruitItem 컴포넌트 추가
import { Component } from "../core/heropy"; export default class FruitItem extends Component { constructor(payload) { super({ tagName: "li", // this element는 li태그로 만들어진다. }); } render() { this.el.textContent = 'Apple'; }
- Component 클래스에 TagName으로 li를 넘겨준다.
1-2. FruitItem 컴포넌트 적용
클래스를 만들었으니 기존에 작성했던 li 태그를 지우고, querySelector로 ul 요소를 찾는다. 그다음 append 메서드를 활용하여 각각의 fruitItem 컴포넌트의 요소 데이터를 배열 데이터로 반환받을 수 있다.
import { Component } from "./core/heropy"; import FruitItem from "./components/FruitItem"; export default class App extends Component { // ... render() { this.el.innerHTML = ` <h1>Fruits</h1> <ul></ul> `; const ulEl = this.el.querySelector("ul"); ulEl.append( ...this.state.fruites .filter((fruit) => fruit.price < 3000) .map( (fruit) => new FruitItem().el ) ); } }
- map 메서드를 사용하여 아이템의 개수만큼 내용을 만들고, 새로운 배열을 반환한다. 이때 새로운 배열은 생성자 함수로 FruitIem 클래스를 호출해서 반환받은 인스턴스 객체값에 해당하는 el. 즉, 요소 부분을 담은 배열이다.
2. 자식 컴포넌트에 데이터 전달(props)
FruitItem 클래스가 호출될 때마다 동적으로 값이 렌더링 되는 방법을 알아보자.
FruitItem 클래스에 props으로 객체 데이터를 할당해 준다. (fruit는 각각의 과일 데이터에 대한 배열 데이터를 의미한다.)
render() { this.el.innerHTML = ` <h1>Fruits</h1> <ul></ul> `; const ulEl = this.el.querySelector("ul"); ulEl.append( ...this.state.fruites .filter((fruit) => fruit.price < 3000) .map( (fruit) => new FruitItem({ props: { name: fruit.name, price: fruit.price, }, }).el ) ); } }
2-1. FruitItem 컴포넌트에서 prop에 대한 로직 추가
FruitItem 컴포넌트로 넘어가서 외부에서 받아온 매개변수인 payload(객체 데이터. 내부에 props라는 속성이 존재함)을 Component 클래스 내에 존재하는 props에 재할당 해준다. 이렇게 하면 props 메서드를 만들 필요 없이 this.props라는 이름으로 메서드 재사용이 가능한데, 이유는 Component 클래스에 payload로 받아오는 데이터 안에 props를 받아서 사용할 수 있는 코드가 존재하기 때문!
import { Component } from "../core/heropy"; export default class FruitItem extends Component { constructor(payload) { super({ tagName: "li", // this element는 li태그로 만들어진다. props: payload.props, }); } render() { this.el.textContent = this.props.name; } }
2-2. 받아온 데이터 화면에 렌더링 해보기
import { Component } from "../core/heropy"; export default class FruitItem extends Component { constructor(payload) { super({ tagName: "li", props: payload.props, }); } render() { this.el.innerHTML = ` <span>${this.props.name}</span> <span>${this.props.price}</span> `; this.el.addEventListener("click", () => { console.log(this.props.name, this.props.price); }); } }
결론
- 컴포넌트도 부모나 자식의 가족 관계를 가지고 있다.
- props라는 단어는 부모 컴포넌트가 자식 컴포넌트에게 내려주는 데이터가 들어있는 속성을 의미한다.
- 부모 컴포넌트에서 일부 데이터를 자식 컴포넌트에게 넘겨주면 복잡한 구조를 쉽게 만들 수 있는 장점이 있다.
📚 배운 점
공통된 로직을 찾고, 분리하고 사용하는 방법이 아직은 어려운데 상황에 맞게 잘 쓰면 좋은 방법 중 하나라는 것을 알게 되었다. 사실 언젠가 한번 자바스크립트로 꼭 SPA 사이트 만들어보세요!라는 얘기를 들었을 때는 SPA라는 구조가 크게 와닿지 않았다. 아마 내가 구현하고자 하는 사이트도 상세 보기 페이지가 없었다면 그냥 싱글 페이지로 쉽게 만들 수 있었을 거고, 그러면 라우팅에 대한 고려나 이런 클래스 컴포넌트에 대한 고민 또한 맞닥뜨리지 못했을 거다. 물론 초기 설계 단계부터 그걸 깨닫고 작업을 진행했으면 좋았을 테지만, 지금이라도 알았으니 다행이지 않은가! 그러니 부지런히 많이 만들어보고 여러 상황을 마주치는 게 매우 중요한 것 같다.😂
[패스트캠퍼스 인강] 프론트엔드 웹 개발의 모든 것 초격차 패키지 Online - API를 활용한 영화 검색 사이트(링크)
💬 본 포스팅은 공부 기록용으로 정확하지 않은 정보가 존재할 수 있습니다. 발견하신다면 알려주세요!
'조각조각 > JavaScript' 카테고리의 다른 글
[JS] 페이징 - 더보기 버튼 (0) 2024.04.08 [JS/class] 클래스로 컴포넌트 구현하기 1 - 컴포넌트 생성 (0) 2024.04.03