> npm install cheerio
- cheerio는 Node 환경에서 파싱을 도와주는 라이브러리입니다.
- 단, 파싱을 도와주는 라이브러리이기 때문에 크롤링 할 페이지는 axios를 이용해 가져와야합니다.
- JQuery 문법을 사용해 css 선택자, class이름, id 등으로 요소를 찾아 데이터를 수집할 수 있습니다.
axios 설치
> npm install axios
- axios는 node.js와 브라우저를 위한 Promise 기반 HTTP 클라이언트입니다.
- 요청 및 응답 데이터 변환, 응답 인터셉트 등의 역할을 합니다.
- 우리는 axios를 이용해 크롤링 하려는 페이지의 html 값을 가져올 것입니다.
Props는 읽기 전용으로 자녀 컴포넌트 입장에서는 변하지 않습니다. 변경하고자 하면 부모 컴포넌트에서 state를 변경시켜주어야 합니다.
2.2.2 Props로 전달
const [todoData, setTodoData] = useState({title: 'todo1', time : 1});
<Lists todoDatas={todoData}/> // 이런식으로 props를 넘겨준다
<자녀컴포넌트 이름 자녀컴포넌트에서 사용할 이름 = {부모컴포넌트에서의 이름} />
//List.js todoDatas 객체 통째로 받고
function List (todoDatas) {
return (
<>
//컴포넌트 내에서 직접 접근
<div>할 일 : {todoDatas.name} </div>
<div>걸리는 시간 : {todoDatas.time} </div>
</>
)
}
//List.js, 애초에 받을 때 구조분해 할당으로 받아버려
function List ({name, time}) {
return (
<>
<div>할 일 : {name} </div>
<div>걸리는 시간 : {time} </div>
</>
)
}
3. 그래서 뭐가 문제야 ? (Props Drilling)
해당 그림은 Root에서 state를 만들고, 이를 Props Drilling 방식으로 하위 컴포넌트에게 state를 내려주고있습니다.
만일 G 컴포넌트에서 상태가 변경되었고, 이를 J 컴포넌트에서 사용해야한다면
G → E → C → A → Root → H → J 순서로 상태가 전달이 것입니다.
코드를 통해서 보면 (참고자료) App > FirstComponent > SecondComponent > ThirdComponent > ComponentNeedingProps
ComponentNeedingProps 컴포넌트에서 해당 Props를 사용하기 위해선 이렇게 전달하는 과정을 거쳐야 합니다.
import React from "react";
import "./styles.css";
export default function App() {
return (
<div className="App">
<FirstComponent content="Who needs me?" />
</div>
);
}
function FirstComponent({ content }) {
return (
<div>
<h3>I am the first component</h3>;
<SecondComponent content={content} />
</div>
);
}
function SecondComponent({ content }) {
return (
<div>
<h3>I am the second component</h3>;
<ThirdComponent content={content} />
</div>
);
}
function ThirdComponent({ content }) {
return (
<div>
<h3>I am the third component</h3>;
<ComponentNeedingProps content={content} />
</div>
);
}
function ComponentNeedingProps({ content }) {
return <h3>{content}</h3>;
}
3.1 Props Drilling
3.1.1 Props Drilling이란?
Props Drilling이란 props를 ‘하위 컴포넌트로 전달하는 용도로만 쓰이는’ 컴포넌트를 거치며 React Component 트리의 한 부분에서 다른 부분으로 데이터를 전달하는 과정이다.
이는 컴포넌트가 3~4개일 때는 문제가 되지 않지만, 여러 개의 컴포넌트가 있을 때는 문제가 될 수 있다.
3.1.2 Props Drilling의 장점
컴포넌트 간에 데이터를 가장 쉽고 빠르게 전달할 수 있다.
작은 규모의 application일 경우, 컴포넌트를 잘게 분해해서 props drilling을 한다면, 코드를 실행하지 않고 정적으로 따라가는 것만으로도 어떤 데이터가 어디서 사용됐는 지 파악하기 쉽고 수정도 용이하다
3.1.3 Props Drilling의 문제점
필요보다 많은 props를 전달하다가, 컴포넌트 분리하는 과정에서 필요하지 않은 props가 계속 남거나 전달되는 문제
props 전달을 누락했는데 default props가 사용되어 props의 미전달을 인지하기 어려운 문제
props의 이름이 전달중에 변경되어 데이터를 추적하기 어려워지는 문제
3.1.4 Props Drilling을 피하려면
렌더링 될 컴포넌트를 불필요하게 여러 컴포넌트로 나누지 않는다.
React는 단 하나의 컴포넌트에 application 전체를 작성하더라도 기술적인 제약이 없다.따라서 불필요한 컴포넌트 쪼개기를 할 필요가 없다.컴포넌트를 재사용해야할 상황을 기다렸다 분할해도 괜찮으며, 불필요한 props drilling을 방지할 수 있다.
defaultprops를 필수 컴포넌트에 사용하지 않는다.
deafultProps를 사용하면 필요한 props가 전달되지 못한 상황임에도 오류가 가려지게된다. 따라서 defaultProps를 필수적이지 않은 컴포넌트에만 사용하면 props drilling으로 인한 문제를 막을 수 있다.
가능한 관련성이 높은 곳에 state를 위치한다.
어떤 데이터가 application의 특정 위치에서만 필요하면 최상위 컴포넌트에 state를 위치시키는게 아닌, 해당 state를 필요로하는 컴포넌트들의 최소 공통 부모 컴포넌트에서 관리하는 것이 효율적이다.
상태관리 도구를 사용한다.
데이터를 필요로하는 컴포넌트가 props drilling의 깊숙히 위치한다면, React의 Context API를 사용하거나, Redux, Recoil 등의 외부 전역 상태관리 라이브러리를 사용해서 문제를 해결할 수 있다.
Children을 사용한다. (Legacy API)
children을 사용하여 리팩토링을 진행하면, 하나의 컴포넌트에서 값을 관리하고, 그 값을 하위요소로 전달할 때 코드추적이 어려워지지 않게됩니다.
그러나 리액트 공식문서에도 나와있듯, children은 잘 사용되지 않고 빈약한 코드 (fragile code)로 이어질 수 있습니다.
4. Context
Context란 application에서 사용할 상태들을 context 내에서 관리하여 보다 컴포넌트들이 편하게 접근 가능하게 합니다.
그림으로 알 수 있듯 Context를 사용하면 Props Drilling을 막을 수 있습니다.
4.1 Context 사용방법
createContext 메서드를 사용해 context를 생성합니다.
생성된 context를 가지고 context provider로 컴포넌트 트리를 감쌉니다.
value props를 사용해 context provider에 원하는 값을 입력합니다.
context consumer를 통해 필요한 컴포넌트에서 그 값을 불러옵니다.
5. 상태관리 라이브러리란 ?
리액트에서 사용하는 데이터를 담는 변수인 State를 전역적으로 관리하는 툴입니다.
상태관리 라이브러리에 대한 자세한 설명은 추후 포스팅하도록 하겠습니다.
cf ) 공식문서 보면서 알게된 어휘인데 ‘from scratch’가 처음부터라는 뜻이었다. 그래서 ‘render from scratch’라 하면 ‘처음부터 렌더링된다’ 라고 해석가능합니다.