Frontender`s Spectre

Using react-beautiful-dnd with Next.js and TypeScript

30 сентября 2022 г., 18:51

Using react-beautiful-dnd with Next.js and TypeScript

Next.js + TS + react-beautiful-dnd

Introduction

react-beautiful-dnd is a higher level abstraction specifically built for lists (vertical, horizontal, movement between lists, nested lists and so on). Within that subset of functionality react-beautiful-dnd offers a powerful, natural and beautiful drag and drop experience. However, it does not provide the breadth of functionality offered by react-dnd. So react-beautiful-dnd might not be for you depending on what your use case is.

(source: https://github.com/atlassian/react-beautiful-dnd)

Motivation

Although it’s straight forward to implement it inside your React application according to its API documentation, it still requires additional configuration in order to make it work in your Next.js application. So, this post will walk you through step by step on how to set up react-beautiful-dnd and fix the potential issues in a Next.js app (using TypeScript). By the end, a simple todo app is introduced as an example to demonstrate react-beautiful-dnd + Next.js + TypeScript in this step-by-step guidance.

Tech Stack

  • Next.js — A widely-used framework for building React applications
  • TypeScript
  • TailwindCSS — A utility-first CSS framework to help you focus on work
  • Nvim — Vim-based text editor

Set up Next.js application with TypeScript, TailwindCSS and vim-based text editor

If it’s your first time of trying to set up a Next.js application with TypeScript and Tailwind together with vim-based text editor, then you probably want to check out my previous post — How to set up a next.js application workflow using Neovim, typescript and tailwindCSS.

After this basic setup, let’s move on implement react-beautiful-dnd in our Next.js application.

Make react-beautiful-dnd works in Next.js

Let’s try to create a simple drop-and-drag Kanban board using DragDropContext, Droppable, and Draggable, from which you will have a basic understanding about drag and drop.

The drag-and-drop components structure looks like this:

Demo a drag-and-drop app (code repo) built with react-beautiful-dnd

A task’s lifecycle: create, delete, reorder and move to other columns

Here are what we want to achieve in the above application:

  • building a droppable container
  • make list items draggable horizontally (within column) and vertically (between columns)

Step 1: Install dependencies

Now you could import the API components from react-beautiful-dnd :

Step 2: Wrap the droppable container with DragDropContext API

Tip: Don’t worry if you could view the whole picture of the React component as the code repo link is shared by the end of this post.

Step 3: Building droppable containers using Droppable API

Building droppable containers to allow items to be draggable horizontally and vertically.

todos.tsx

Don’t get overwhelmed by the above code. The only thing you need to understand is that a Droppable container is created using Droppable component, and you must provide droppableId which could be any unique string, and a callback function: (droppableProvided) => (..ref={droppableProvided.innerRef} {…droppableProvided.droppableProps}). That’s all for creating a Droppable container. In the next, we will create Draggable component to be

Step 3: Implement Draggable feature inside Droppable containers using Draggable API

todoitem.tsx

Same as Droppable component, we also need to provide a draggableId which is any unique string, and a callback function: (draggableProvided) => (..ref={draggableProvided.innerRef} {…draggableProvided.draggableProps} {...draggableProvided.draghandleProps).

Step 4: Run your Next.js application and issues occur

Issue #1: Unable to find any drag handles in the context “0”

Solution: Override Document

The server side rendering feature of Next.js could mess up how a library operates, and one such library is react-beautiful-dnd.To fix the above issue, we need to use resetServerContext call inside Document so that the markup from the server doesn’t conflict with what the client side library(dependency) expects (react-beautiful-dndin our case). Then we need to override the default Document(pages/_document.js), which is shown below:

You can follow the docs for the _document here: https://nextjs.org/docs/advanced-features/custom-document

We need to import resetServerContext from react-beautiful-dnd and call it in our getInitialProps before we return. So, here is what_document looks like:

Issue #2: Cannot find droppable entry with id

Up to now, you might still see problems similar to below:

Solution: remove reactStrictMode

You could find this issue discussed as well in Github issue page. Not too bad as it only happens in development env, but not in production env. Yet, to make our development easy, we simply need to comment out the below code inside next.config.js

// reactStrictMode: true,

Build a todo app using react-beautiful-dnd + Next.js + TypeScript

You could find a Todo app using react-beautiful-dndin the repo: https://github.com/amy-juan-li/example-dnd-todo