티스토리 뷰
kentcdodds.com/blog/application-state-management-with-react
요약
리액트에서 상태관리를 위해 항상 Redux를 관습처럼 사용한다. 심지어 컴포넌트 내부에 위치해도 괜찮은 local State까지 Redux를 통해 global하게 관리하는 사람도 많이 봤다. 그렇게 하지말고 차라리 state의 선언 위치를 그 state를 필요로 하는 컴포넌트 그룹의 최상위로 올린다음 props drilling으로 해결해라.
그렇게 하는데 한계가 있을때는 아래와 같이 Context API를 사용하라.
function CountProvider(props) {
const [count, setCount] = React.useState(0)
const value = React.useMemo(() => [count, setCount], [count])
return <CountContext.Provider value={value} {...props} />
}
여기서 중요한건 Provider에 제공하는 value가 매번 새롭게 만들어지기 때문에 useMemo로 감싸줘야한다는것이다. useMemo를 통해 count값이 변경됬을때만 value가 재생성되게끔 만들어주면 해당 value값을 소비하는 Consumer들은 count값이 바뀌었을때만 리렌더링된다.
Props Drilling에 대한 오해
그동안 나는 Props drilling은 피해야하는 방식이라고 생각을 했으나 이 포스트를 보고 생각이 바뀌었다. kent는 오히려 props drilling을 권장한다. 왜냐면, 변수들이 선언되고 사용되는곳들이 서로 붙어있을수록 유지보수하기 쉽기 때문이다. props drilling을 한다는것은 해당 변수값들이 어디서 선언되었으며 어디서 사용되고 어디서 업데이트되었는지 명확하게 알 수 있게 해준다. 이것을 Redux와 같이 global state로 관리할수도 있겠지만 그렇게 되면 오히려 더 많은 파일(액션, 비동기 로직, 리듀서, 셀렉터)등을 열어가며 확인해야하기 때문에 state를 공유해야 하는 컴포넌트 트리의 뎁스가 얕다면 그냥 props drilling을 사용하라.
그렇다면 depth가 깊은 컴포넌트 트리에서 서로 다른 Depth에 있는 컴포넌트들이 같은 state를 공유해야할때는 어떻게 해야 할까?
이때도 props drilling을 해야 할까? 그렇지 않다. 물론 해도 상관은 없지만 만약 그 state의 변수명을 살짝이라도 바꿔야 하는 경우 그 하위에 선언된 모든 이름을 바꿔줘야한다. 지옥이 펼쳐질 수 있다.
최대한 props drilling 문제를 피하기 위해서는 컴포넌트의 depth를 깊게 만들지 않아야 한다. 가끔 컴포넌트를 재활용하지도 않는데 보기 편하게 하려고 여러 컴포넌트로 나눈경우가 있다. 당연히 컴포넌트가 잘게 쪼개져있으면 코드를 파악하는 시간은 줄어들 수 있겠지만 오히려 props drilling에 대한 비용은 커진다.
그러므로 컴포넌트를 쪼개야할까 말까?에 대한 고민은
쪼개진 컴포넌트가 다른 컴포넌트에서도 재활용되는가?를 기준으로 생각하라.
> 이부분은 참 어렵다.
1. 컴포넌트를 잘게 나누어 렌더링을 최적화 하고 코드 파악 시간을 줄이는것
2. 저자의말대로 props drilling에 대한 비용을 줄이는것
어떤것이 더 유지보수에 도움될까? 아직은 잘 판단이 되지 않는다. 서로 trade-off 관계에 있지 않나 싶다.
아마 본인만의 기준이 필요하지 않을까?
예를들어서, "컴포넌트 Depth 3까지는 Props drilling을 사용한다"와 같은.
아무튼 깊은 컴포넌트 트리에 대해서는 Context API를 사용하라.
컴포넌트의 필수 props에 defaultProps를 설정하지마라.
컴포넌트가 조용하게 잘못 렌더링 되는 경우가 생길 수 있다. 옵셔널한 값에만 defaultProps를 설정하라.
'React' 카테고리의 다른 글
컴포넌트의 네이밍 (0) | 2021.05.05 |
---|---|
React Fiber가 가지는 장점 (0) | 2020.08.03 |
React Fiber 소개 (0) | 2020.08.03 |
React에서의 데이터 정규화(normalizr) (0) | 2020.07.30 |
[ver 2020.07.27] FrontEnd Architecture(Mobx, React, React-Router) (0) | 2020.07.27 |
- Total
- Today
- Yesterday
- typescript
- mobx
- reducer
- hydrate
- async
- reactdom
- javascript
- atomic design
- promise
- await
- react
- props
- Polyfill
- webpack
- server side rendering
- state
- computed
- reflow
- rendering scope
- type alias
- useRef
- react hooks
- design system
- storybook
- useEffect
- return type
- es6
- Babel
- Action
- Next.js
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |