Q. 상태 관리를 하는 이유는 뭘까?
보통 부모자식관계에 있는 컴포넌트들은 state를 props로 전달하게 된다. 이 데이터는 부모에서 자식으로 가기도, 자식에서 부모로 전달되기도 한다.
props drilling이라는 것은 props가 상위 컴포넌트에서 하위 컴포넌트들을 통해서 전달되는 것을 뜻하는데, 이것 자체가 문제가 되는 것은 아니다. 하지만 컴포넌트간 상태 의존도가 높아져 너무 여러 컴포넌트를 거치게되면 이 props가 어디에서 시작된 것인지 추적을 하기가 힘들기 때문에 유지 보수를 하는데 문제가 생긴다. 따라서 상태 관리를 전역에서 할 수 있는 tool이 필요하다.
Q. 상태관리, 지금 어떻게 하는지?
현재 개인적으로 지역상태는 props로 관리하며 프로젝트가 커지고 컴포넌트간 상태 의존성이 높아지면 전역 상태관리 툴인 Redux의 Redux toolkit을 사용하고있다. Redux는 props dirlling을 해결하기 위한 방안으로 널리 쓰이고 있고 가장 큰 커뮤니티를 보유하고 있음.
Redux는 쓰기가 복잡하고, 보일러 플레이트를 많이 써야하는 점 등이 불편함. 때문에 이런 점을 개선하고자 나온 것이 Redux-toolkit이다.
RTK는 immer가 내장되어 있어 상태의 불변성을 지키는 것이 매우 편리하고, 타입스크립트를 지원하며, redux thunk, redux saga가 내장되어있어 비동기 작업에 수월하고 Redux보다 간편하게 사용이 가능한 장점이있다.
이 외에도 Context API, Recoil 등 다른 전역 상태관리 툴이 있다.
Context API는 React 자체 내에서 제공하는 API로 일일이 props를 넘겨주지 않고도 컴포넌트 트리 전체에 데이터를 제공할 수 있다.
주된 용도는 다양한 레벨에 네스팅된 많은 컴포넌트에게 데이터를 전달하는 것이다. context를 사용하면 컴포넌트를 재사용하기가 어려워지므로 꼭 필요할 때 써야한다. 차라리 컴포넌트 합성이 더 간단한 해결책일 수 있음.
Recoil은 React를 위한 상태관리 라이브러리이다. 사용하기가 쉽다고 한다. React의 Hook을 사용하는 사람들에게 익숙하다. 어플리케이션을 RecoilRoot로 감싸고, 데이터를 atom이라는 단위로 선언해 useState대신에 useRecoilState로 대체해야 한다.
또한, 컴포넌트가 사용하는 데이터 조각만 사용할수 있고, 계산된 selector를 선언할 수 있으며, 비동기 데이터 흐름을 위한 내장 솔루션을 제공한다. Redux보다 가볍다는 큰 장점도 있음.
그러면 props와 state의 차이점은?
props 와 state 모두 JavaScript의 객체이다. 두 객체 모두 렌더링시 결과물에 영향을 주는 정보를 갖고있는데, props는 컴포넌트에 전달되는 반면에, state는 컴포넌트 안에서 관리된다.
* props?
props는 state를 간단하게 전달 해 주는 편리한 객체(properties)이다.
상위 컴포넌트에서 하위 컴포넌트로 전달 가능한 단방향 데이터 흐름을 갖는다.
자식 컴포넌트에서는 props를 받아오기만하고, 직접 수정 할 수는 없다.
defaultProps로 기본값 설정이 가능하다.
//Nondi.js
import React from 'react';
function Nondi({color, name}) {
return <div style={{color}}>안녕하세요 {name}</div>
}
Nondi.defaultProps = {
name: '이름없음'
}
export default Nondi;
props.children
컴포넌트 태그 사이에 넣은 값을 조회하고 싶을 땐, props.children을 조회한다.
import React from 'react';
function Wrapper() {
const style = {
border: '2px solid black',
padding: '16px',
}
return (
<div style={style}>
<div>
)
}
export default Wrapper;
이 컴포넌트를 상위 컴포넌트에서 import 해오기
import React from 'react';
import Nondi from './Nondi';
import Wrapper from './Wrapper';
function App() {
return(
<Wrapper>
<Nondi name="react" color="red"/>
<Nondi color="pink"/>
</Wrapper>
);
}
export default App;
이렇게 Wrapper 태그 내부에 Nondi 컴포넌트 두개를 넣었는데 브라우저를 확인하면 Nondi 컴포넌트들은 보이지 않음.
내부의 내용이 보여지게 하려면 Wrapper에서 props.children을 렌더링 해주어야 한다.
Wrapper.js
import React from 'react';
function Wrapper({children}) {
const style = {
border: '2px solid black',
padding: '16px',
}
return (
<div style={style}>
{children}
<div>
)
}
export default Wrapper;
* state는 뭘까?
동적인 데이터를 다룰 때 사용되어지는 값이다.
컴포넌트에서 사용하는 값으로, 값을 수정하고 사용할 수 있다.
References:
https://react.vlpt.us/basic/05-props.html
https://ui.toast.com/weekly-pick/ko_20200616
'공부 정리' 카테고리의 다른 글
22.11.09 : webpack (0) | 2022.11.09 |
---|---|
22.11.08 : TCP, UDP (0) | 2022.11.08 |
22.11.07 : JavaScript의 비동기 처리방식과 비동기 함수 (0) | 2022.11.07 |
22.11.07 : DOM (Virtual DOM vs Real DOM) (0) | 2022.11.07 |
22.11.05 : Redux란 무엇인가요? 왜 사용하시나요? (0) | 2022.11.05 |