Next.js CRUD with MongoDB
With the launch of Next.js in 2016, this framework has soon adopted by many companies in building full-stack applications, which handle both the frontend and backend of the app and were using Javascript and React. Several features that Next.js provides include SSR, pre-rendering, better user experience, SEO, and page speed. Perhaps the fascinating feature is the pre-rendering of the web page, the HTML to render is produced on the server-side and sent to the client-side, and the search engine will get HTML from the server instead of executing the Javascript code for getting the HTML.
With some experience in React, I decided to develop a project made using Next.js and connect with MongoDB: A donation application aims at collecting goods and materials demand information from charities and provides the user to donate money, foods, or goods to someone in need. (Still an ongoing project, many pages are not available🚂…)
On the home page, there will be a section that displays the category of donation and related information, and we can manipulate the data on the setting page, below is a brief introduction to creating, reading, updating, and deleting actions of the category information.
File-based routing is introduced in Next.js, when we create a file under the “Page” directory, it will automatically create a path name with the file name, for example, pages/settings.jsx, will be accessible at https://xxx.com/settings
. The pages/API
directory is mapped to /API/*
. Files in this directory are treated as API routes instead of React pages. For categories API request, we’ll define the CRUD functions under pages/api/cards/index.js
:
For data fetching, we are using useSWR
React hooks library, SWR is an abbreviation of Stale-While-Revalidate, it fetches data from an API, then saves data in a cache, and renders the data. Since data will be saved in cache from the API call, it is fast to switch between different components. In addition, if an API call depends on the response of other API calls, useSWR
provides a way to add the response from the previous call to the next API call’s key, so that SWR will execute the request after the previous call. For other features, like conditional data fetching, refetch on interval, please check its documentation.
We use useSWR(key, fetcher)
to fetch the data, key is a unique key string for the request, fetcher is a Promise returning function to fetch your data, let’s define a fetcher and the card hook, which is a reusable data hook build on top of SWR, if we want to get category information, we just need to use useCards in the component page.
Below is an example of a post, patch and delete request of the category settings, the table listed out all the categories and some actions, which will pop out an edit or delete modal. Since the code is quite long, I’ll demonstrate a fraction of the file:
onSubmit function takes in a method parameter, which is defined in the dialog component, once the user open the dialog and save the form, we then first decide whether this is a newly created form or an already exist form, then make a POST or PATCH request accordingly. We passed in api/cards
with the input of Title
, Content
, URL
, Tags
, Image
, which were all saved under the values
object. If saved successfully, the mutate() function is called to update the card cache. At the same time, you will see an added item in the listed category table.
Since the table in this website are nearly identical, it’s better implement a common template. I use react-table as the table template called SingleTableList
that handles all the table related UI and function. The child component added under SingleTableList
is the common form that will be passed in the modal, when the user click on add, edit or delete, the child component that includes the label or input fields will be rendered to the modal. In addition, I added a filter on the top of the table, which user will be able to search for certain item in the table. The table template can be checked here.
Also, we may have more rows of data added to the table, adding pagination or a load more button is a choice for better user experience, I add a previous and next button, and add a limitation of 5 data in a page of table.
What if we want to show different background color based on a certain range of number. For example, the partner table recorded which year the charity were founded, if someone wants to check the charities’ info that founded between 2010 to 2015, we can give a color for that cell within the range. Here, I added a binary search function that takes in an array and the value of the field, this function will return which section that the number is located at. Finally, in the css file, we then set the foreground and background color for each section.
Hope that the above demonstration can give you a brief understanding of the basic CRUD request in Next.js app, I’ve also deployed the app on Heroku and Github, feel free to check for more information.