Created
July 31, 2022 22:04
-
-
Save natafaye/476671cce2725a17911276763fad6ab3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React, { useEffect, useState } from 'react' | |
| const fetchAllTasks = async () => { | |
| try { | |
| const response = await fetch("/api/tasks"); | |
| // Check if the server successfully responded but the response says something went wrong | |
| if(!response.ok) { | |
| // You could return a nicer error message here instead of just null | |
| return null; | |
| } | |
| const data = await response.json(); | |
| return data.tasks; | |
| } | |
| catch (error) { | |
| // Handle issues that happen before we can even get a response (internet issue, backend down) | |
| // You could return a nicer error message here instead of just null | |
| return null; | |
| } | |
| } | |
| const deleteTask = async (id) => { | |
| try { | |
| const response = await fetch("/api/tasks/" + id, { method: "DELETE" }) | |
| if(!response.ok) { | |
| return null; | |
| } | |
| return true; | |
| } | |
| catch (error) { | |
| return null; | |
| } | |
| } | |
| export default function App() { | |
| const [taskList, setTaskList] = useState( [] ) | |
| // Create some kind of loading piece of state (usually a boolean) | |
| const [loading, setLoading] = useState(false); | |
| // Create some kind of error piece of state (usually a message) | |
| const [errorMessage, setErrorMessage] = useState(null); | |
| const refreshTasks = async () => { | |
| setLoading(true); | |
| const freshTasks = await fetchAllTasks(); | |
| if(freshTasks) { | |
| setTaskList(freshTasks); | |
| setErrorMessage(null); | |
| } | |
| else { | |
| setErrorMessage("Failed to fetch") | |
| } | |
| setLoading(false); | |
| } | |
| useEffect(() => { | |
| refreshTasks(); | |
| }, []) | |
| const onDeleteClick = async (id) => { | |
| // Set it to true when we start the process | |
| setLoading(true); | |
| const deleteResult = await deleteTask(id); | |
| if(deleteResult) { | |
| setErrorMessage(null); | |
| // Only refresh if delete worked | |
| await refreshTasks(); | |
| } | |
| else { | |
| setErrorMessage("Delete failed") | |
| } | |
| // Set it to false when everything is done (make sure to wait) | |
| setLoading(false); | |
| } | |
| return ( | |
| <> | |
| <ul> | |
| { /* Conditionally render the error message */ } | |
| { errorMessage ? <li className="text-danger list-unstyled">{ errorMessage }</li> : null } | |
| { /* Conditionally render the loading message */ } | |
| { loading ? <li className="text-muted list-unstyled">Loading...</li> : null } | |
| { taskList.map(task => ( | |
| <li key={task.id}> | |
| { task.name }{" "} | |
| { /* You could use the loading piece of state to disable buttons or change button text */ } | |
| <button disabled={loading} onClick={() => onDeleteClick(task.id)}>{ (loading) ? "Loading..." : "Delete" }</button> | |
| </li> | |
| ))} | |
| </ul> | |
| </> | |
| ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment