Thu, Apr 30, 2015
This example is basically a Trello clone: We have a set of lists of tasks ("Todo", "Done"), and each holds some tasks. We can add tasks, delete them, or drag them from one list to the other. We'll React DnD for drag-and-drop and a simple Python server for persistence.
August 2018: Please note that this post was written for an older version of React. Changes in the code might be necessary to adapt it to the latest versions and best practices.
We'll be using Flask for the server, since we don't need much. First, the imports and the app definition:
Now, some barebones models:
For persistence, we'll just use the memory:
And now, the routes. This is just a simple REST API that uses JSON, handles actions and even some errors. First, we need a route that will be called on application startup, to get the initial (or current) state of the Kanban board:
We also need a way to add new tasks to a list, which is what
And a way to delete tasks:
Finally, we use the root route to serve the
And now we tell Flask to always run the server on port 8000:
First, let's import the
Since we're only moving one type of component, tasks, we declare that:
First, we define the
Task component. Since we're going to be dragging it from task list to task list, we use the
We then implement the
beginDrag function and register it with React DnD. Whenever a task is dragged, we carry the task's text and deletion callback along with it.
Then we implement
AddTask, a sub component of
TaskList for adding new tasks to the task list:
TaskDropBin is the component in a
TaskList where tasks being dragged can be dropped into.
deleteTask method, which removes it from its original list, and call the
addTask method of the drop bin's parent task list to add the task to the list.
We query the component's drop state and set its class name accordingly. We'll later use this to decide whether to show or hide it, and change its color to let the user know when they can drop a component into the bin.
Finally, the task list itself. Since it holds a list of tasks which can be deleted, and to which new ones can be added, we make that a big of state:
addTask methods send requests to the server to carry out the operations in the backend so data remains consistent.
Now we have the render function, which builds up the list of Task components along with other things, like the list’s title, its task drop bin and AddTask component.
Finally, the app component. This is just a wrapper around the other components that wraps TaskList components in a div.
Once the document has loaded, we ask the server for the initial state of the board, and render that using the App component:
And finally, we add some style. First, general body style:
Next, we style the task lists:
The task list’s drop bin is just a big rectangle with the text "Drop here", which is not very complicated to style:
Since we change the class of the task list’s drop bin depending on its state, we use this state to style it. When the state is none, we hide it, on the two other states, we change the color: Orange when a task is being dragged around, and green when it is hovering over a drop bin.
Finally, some style for the individual tasks:
And we use the CSS content property to put a Unicode times symbol and make a neat little delete button:
When I wrote the first version of this app, it had no drag and drop, and the only thing you could do was add and delete items from lists. So after a short exploration of drag and drop in React, I rewrote this with drag and drop support, which was far easier than I expected. React DnD is very intuitive and doesn’t require really thinking much about the task, you just include some mixins and pass some props and define a couple of functions and that’s it.
The code, as a whole, is very short. Just 150 lines, with the CSS stylesheet being a third of that. React really is an amazing tool.