본문 바로가기
우아한 테크코스

재사용 가능한 컴포넌트 Grid 오류

by 해-온 2023. 9. 18.

문제 상황

 

Chakra UI - A simple, modular and accessible component library that gives you the building blocks you need to build your React a

Simple, Modular and Accessible UI Components for your React Applications. Built with Styled System

chakra-ui.com

 

 

Chakra UI를 보면서 재사용 가능한 컴포넌트를 만들었다.

그중 Grid의 Starting and ending lines를 참고해 row와 column의 시작점과 끝점을 정의했다.

 

gridColumn: col === 'auto' ? 'auto' : `span ${col} / span ${col}`,
gridRow: row === 'auto' ? 'auto' : `span ${row} / span ${row}`,
gridColumnStart: colStart,
gridColumnEnd: colEnd,
gridRowStart: rowStart,
gridRowEnd: rowEnd,

 

코드에 이렇게 grid와 관련한 속성이 들어갔는데

 

잘 되는 듯하였지만, 아래 코드일 경우 첫 번째 grid item에 grid 속성이 부여되지 않는 오류가 생겼다.

 

<Grid columns={5} gap={4}>
  <GridItem col={2} height='30px' bgColor='#D8EAFF' />
  <GridItem colStart={4} colEnd={6} height='30px' bgColor='#FFEC99' />
</Grid>

 

grid 속성이 아예 적용되지 않은 것을 볼 수 있다.

 

근데 col 부분에 숫자를 3으로 바꾸고 다시 2로 바꾸면 grid 속성이 적용된다.

 

//여기 col 부분을 col={3} -> 저장 -> col={2}
<GridItem col={2} height='30px' bgColor='#D8EAFF' />

 

그리고 다시 새로고침을 하면 grid-column이 사라진다.

추측이지만 시작점과 끝 지점을 적용하는 저 props가 기존의 grid를 덮어버리는 듯하다.

 

따라서 row와 column의 시작, 끝점을 적용하는 props를 삭제하고 row와 column props에 넣어주었다.

 

gridColumn: `${col && col !== 'auto' ? `span ${col} / span ${col}` : ''} ${
      colStart && colEnd ? `${colStart} / ${colEnd}` : ''
  }`,
gridRow: `${row && row !== 'auto' ? `span ${row} / span ${row}` : ''} ${
  rowStart && rowEnd ? `${rowStart} / ${rowEnd}` : ''
}`,

 

근데 이렇게 적으면 일단 복잡해 보이는 것은 물론이고,

사용자가 시작점이나 끝지점 둘 중 하나를 작성하지 않으면 grid가 제대로 적용되지 않는 문제가 있다.

 

그래서 기본값을 모두 'auto'로 주는 방법도 생각해 봤으나

관련 props를 하나라도 입력하지 않으면 모두 'auto'로 적용돼 grid가 제대로 적용되지 않는다.

 

 

해결 방법

col, colStart, colEnd / row, rowStart, rowEnd 속성을 같이 쓰게 되면 스타일이 겹쳐서 원하는 대로 동작하지 않는다.

grid-column → grid-column-start / grid-column-end로 동작하기 때문이다.

 

<GridItem col={2} colStart={4}>아이템1</GridItem>

 

위 코드를 실행하면 colStart 속성이 더 하단에 있어서 col을 덮어쓴다.

 

 

colStart는 있지만 colEnd는 없어 undefined로 잡히는 것으로 추정된다.

즉, span 2 / span 2에서 4 / undefined가 되고 결국 4가 되는 것이 아닐까?

(참고로 css에서 undefined는 문자열로 해석되며, 정의하지 않은 것으로 간주해 스타일링을 적용하지 않는다고 한다)

 

이를 어떻게 해결할 수 있을까?

 

Chakra 코드를 보면 compact라는 함수가 있다.

https://github.com/chakra-ui/chakra-ui/blob/main/packages/utilities/object-utils/src/compact.ts#L1

이 함수는 객체에서 값이 undefined인 속성을 삭제한다.

 

export const compact = <T extends Record<any, any>>(object: T) => {
  const clone = Object.assign({}, object);
  for (let key in clone) {
    if (clone[key] === undefined) delete clone[key];
  }
  return clone;
};

 

Chakra의 grid item 컴포넌트를 보면 이 compact 함수로 감싸주고 있다.

그래서 나도 이 compact 함수를 스타일 객체에 감싸줬다.

 

<GridItem col={2} colStart={4}>아이템1</GridItem>

 

아까는 grid-column-start: 4로 나타나던 속성이

 

 

grid-column: 4 / span 2로 바뀐 것을 볼 수 있다.

 

<GridItem col={2} colEnd={4}>아이템1</GridItem>

 

이 경우도 span 2 / 4로 제대로 적용된 것을 볼 수 있다.

 

<GridItem col={2} colStart={2} colEnd={6}>아이템1</GridItem>

 

만약 사용자가 3개 다 적는다면 완전히 다 덮여서 2 / 6으로 적용됨을 볼 수 있다.

 

 

 

 

댓글