During a recent interview, I was presented with an intriguing challenge: create a basic CRUD (Create, Read, Update, Delete) application using React and Typescript. I found this task to be both engaging and enjoyable, so I decided to share my solution with you. In this blog post, I'll walk you through the process of building a simple CRUD app with only front-end functionality. Additionally, I'll demonstrate how to persist the app's state using local storage, enabling data retention even when the user refreshes their browser. Although error handling has been simplified through alert messages for the sake of simplicity, you can easily enhance it later on.
Building the CRUD App:
To start, I approached the task by designing a custom hook that would handle all the necessary functionality. This hook would encapsulate the logic for creating, reading, updating, and deleting data, allowing us to easily access the required functions. To provide a seamless user experience, it's essential to preserve the application's state even when the browser is refreshed. To achieve this, I utilized the local storage feature available in modern web browsers. By leveraging the local storage API, we can store the app's data and retrieve it when needed, ensuring continuity between sessions.
export const useCRUD = () => {
const [items, setItems] = React.useState([] as string[]);
const setItemsWithStorage = (items: string[]) => {
setItems(items);
localStorage.setItem("items", JSON.stringify(items));
};
React.useEffect(() => {
const items = localStorage.getItem("items");
if (items) {
setItems(JSON.parse(items));
// Also get from backend here
}
}, []);
const addItem = (item: string) => {
if (items.includes(item)) {
alert("List already contains item");
return;
}
setItemsWithStorage([...items, item]);
// Also add to backend
};
const deleteItem = (item: string) => {
if (!items.includes(item)) {
alert("Item not in list");
return;
}
const filtered = items.filter((v) => v !== item);
setItemsWithStorage(filtered);
// Also add to backend
};
const getItems = () => items;
const updateItem = (prevItem: string, newItem: string) => {
if (!items.includes(prevItem)) {
alert("Item not in list");
return;
}
if (items.includes(newItem)) {
alert("List already contains item");
return;
}
const newItems = items.map((i) => (i === prevItem ? newItem : i));
setItemsWithStorage(newItems);
// Also update in backend
};
return { addItem, deleteItem, getItems, updateItem };
};
While this project presents a simplified version designed to demonstrate the proof of concept during an interview, I thoroughly enjoyed the process and saw it as an excellent opportunity to showcase my skills. I would love to hear your thoughts on how you would approach this problem. Would you have also opted for a custom hook, or would you have pursued a different approach? Please share your insights in the comments below; I'm eager to learn from your perspective. I hope this tutorial has been valuable to you in your journey of building React Typescript CRUD apps.
You can find my example here: https://codesandbox.io/s/simple-crud-app-2lxj6k?file=/src/App.tsx
Top comments (0)