티스토리 뷰

React

React-virtualized의 AutoSizer

심재철 2020. 6. 15. 12:48

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으로 설정해서 자식에 따라 부모가 같이 커지는 일을 방지 할 수 있다.

flex conatiner의 너비가 200px인데 자식의 너비가 60px * 4 = 240px이라 flex container의 너비도 240px이 되었다.
AutoSizer의 width와 height가 0으로 설정된것을 볼 수 있다.

AutoSizer가 width나 height중 하나만 채우게 할 수 있나요?

disableHeightdisableWidth를 활용하면 가능하다.

<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>

마찬가지로 ListAutoSizer로 감싸주면 사용 가능합니다.

 

댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함