티스토리 뷰
AutoSizer
부모 element의 너비와 높이를 자식 컴포넌트에 전달해주는 HOC이다. 이걸 활용하면 부모의 너비와 높이만큼 자식을 꽉 채울 수 있다.
옵션값
children
({ height: number, width: number }) => PropTypes.element
이런 형태여야함.
className, style
AutoSizer에 추가됨
defaultWidth, defaultHeight
SSR시 초기 너비와 높이값. 정확한 값이 계산되면 그 값으로 대체됨.
disableWidth, disableHeight
고정된 width와 height
nonce
Nonce of the inlined stylesheets for Content Security Policy
onResize
리사이징될때 호출되는 콜백 함수
({ height: number, width: number }).
예제
많은 react-virtualized 컴포넌트들은 명시적인 너비와 높이를 지정해야한다. 근데 때로는 가능한 공간만큼 알아서 채웠으면 좋을때가 있다. 그럴때 AutoSize를 사용하라.
Autosizer를 flex 컨테이너의 자식으로 넣지 말아라. AutoSizer는 블럭 컨테이너 내부에 있어야 제대로 동작한다. 왜냐면, flex container는 자식의 크기가 얼마나 되든 유연하게 늘어나기 때문에 자식의 크기를 고정시키가 어려워진다.
javascript-detect-element-resize 알고리즘
AutoSizer는 자동으로 너비와 높이를 계산하기 위해서 이 알고리즘을 사용한다. 타겟의 부모를 position:relative로 설정한다음에 타겟의 형제로 빈 div를 넣어서 사이즈 변화를 탐지하는 알고리즘이다.
왜 AutoSizer는 height를 0으로 만드나요?
AutoSizer는 부모의 크기만큼 커지지만 부모 자체의 사이즈를 늘리지는 않는다. 하지만 부모가 flex container일 경우 자식의 크기가 커짐으로써 컨테이너의 크기도 같이 늘어나는 경우가 생길 수 있다. 그렇게 되면 이런 무한루프가 발생한다.
AutoSizer의 크기 증가 -> flex container의 크기 증가 -> AutoSizer가 다시 증가된 flex Container를 채움 -> flex Container의 크기 다시 증가 -> ... 무한반복
따라서, AutoSizer의 width와 height를 0으로 설정해서 자식에 따라 부모가 같이 커지는 일을 방지 할 수 있다.
AutoSizer가 width나 height중 하나만 채우게 할 수 있나요?
disableHeight나 disableWidth를 활용하면 가능하다.
<AutoSizer disableHeight>
{({width}) => <Component height={200} width={width} {...props} />}
</AutoSizer>
이렇게 하면 height는 200px로 고정되고 width는 부모의 크기만큼 자동으로 증가된다.
Flex Container 내부에서 AutoSizer를 사용하고 싶으면?
<div style={{ display: 'flex' }}>
<!-- Other children... -->
<div style={{ flex: '1 1 auto' }}>
<AutoSizer>
{({ height, width }) => (
<Component
width={width}
height={height}
{...props}
/>
)}
</AutoSizer>
</div>
</div>
이런식으로 한번더 flex로 감싸줘야한다. 두겹의 flex container가 필요하다. (정확히 어떤 원리에 의해서 두겹의 flex container일떄는 정상 동작하는지 설명되어있지 않다. 혹시 아시는분은 댓글 달아주시면 감사합니다.)
AutoSizer를 다른 HOC(InfiniteLoader)와 함께 사용할 수 있나요?
<InfiniteLoader {...infiniteLoaderProps}>
{({onRowsRendered, registerChild}) => (
<AutoSizer>
{({height, width}) => (
<List
ref={registerChild}
width={width}
height={height}
onRowsRendered={onRowsRendered}
{...listProps}
/>
)}
</AutoSizer>
)}
</InfiniteLoader>
마찬가지로 List를 AutoSizer로 감싸주면 사용 가능합니다.
'React' 카테고리의 다른 글
내가 React의 setState를 안쓰는 3가지 이유(Mobx로 local state 관리하기) (0) | 2020.06.26 |
---|---|
React-virtualized의 CellMeasurer (0) | 2020.06.15 |
JSX element type 'TabComponent' does not have any construct or call signatures. (0) | 2020.06.03 |
JSX.Element vs ReactNode vs ReactElement의 차이 (1) | 2020.05.21 |
당신의 프론트엔드를 리액트로 이전하는 방법 (0) | 2020.05.15 |
- Total
- Today
- Yesterday
- await
- hydrate
- typescript
- mobx
- Next.js
- type alias
- rendering scope
- Action
- props
- computed
- useEffect
- return type
- react
- storybook
- react hooks
- webpack
- useRef
- design system
- reducer
- Polyfill
- javascript
- reflow
- atomic design
- async
- server side rendering
- reactdom
- promise
- es6
- state
- Babel
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |