React-Beautiful-dnd와 Next.js에서의 트러블슈팅

이현우·2024년 3월 1일
1

issue 1: SSR과 react-beautiful-dnd의 호환성

Next.js의 서버 사이드 렌더링(SSR)과 react-beautiful-dnd(@hello-pangea/dnd)의 호환성 문제로 초기 렌더링 시에 data-rbd-draggable-context-id did not match.경고가 발생했다.

  • solution
import dynamic from 'next/dynamic';
const Droppable = dynamic(
  () => import('@hello-pangea/dnd').then(mod => mod.Droppable),
  { ssr: false }
);

const Draggable = dynamic(
  () => import('@hello-pangea/dnd').then(mod => mod.Draggable),
  { ssr: false }
);

next/dynamic을 사용하여 Droppable과 Draggable 컴포넌트를 동적으로 임포트하고, { ssr: false } 옵션을 통해 이들이 클라이언트 사이드에서만 로드되도록 설정했다. 이 방법으로 서버와 클라이언트 사이의 불일치 문제를 해결하였다.

  • 동적로딩을 하면 클라이언트 사이드에서만 로드되는 이유

Next.js 같은 서버 사이드 렌더링을 지원하는 프레임워크에서 dynamic 함수를 사용하여 컴포넌트를 동적으로 로드하는 경우, 이 로드 과정은 브라우저가 페이지를 불러온 후, 클라이언트에서 발생한다.

  • getServerSideProps 를 적용하지 않았는데도 서버 사이드 렌더링을 하는 이유

Next.js는 페이지를 방문하는 첫번째 요청에 대해 자동으로 서버에서 페이지를 렌더링한다.


issue 2: input 요소가 포함된 컴포넌트에서 drag & drop이 잘 작동하지 않는 상황

사용자가 li 태그의 전체 영역이 아니라, 일정부분에서만 드래그를 할 수 있었다. input 요소가 drag & drop 동작을 방해한 것으로 판단했다.

  • solution

todo-list안의 todo-item은 props로 disabled 속성을 전달했었고, 이들은 input 요소로서 쓰일 필요가 없기 때문에 span 태그로 대체하였다.

export default function TodoItem({
  checked,
  handleCheckboxChecked,
  className,
  children,
  ...props
}: IProps) {
  return (
    <div
      className={clsx(styles.item, className)}
    >
      <CheckboxButton
        className={styles['checkbox-button']}
        checked={checked}
        onChange={handleCheckboxChecked}
      />
      {
        props.disabled ?
          <span
            className={clsx(
              {
                [styles.checked]: checked,
                [styles.disabled]: props.disabled
              }, styles.input)}
          >
            {props.value}
          </span>
          :
          <input
            className={clsx(
              {
                [styles.checked]: checked,
                [styles.disabled]: props.disabled
              }, styles.input)}
            {...props}
          />
      }
      {children}
    </div>
  );
}

0개의 댓글