rsnext/examples/blog-with-comment/hooks/useComment.ts
Joseph 6fb3993fdc
fix: Check if the GET comments response was ok, otherwise throw (#62041)
Fixes #61941 example blog-with-comment.

The root issue is that the SWR fetcher does not check the `ok` status of the response, and that way we end up putting the error message object into the SWR data. And then `.map` is invoked in the object.

Since this is a learning kind of example, I think perhaps the presented change is just about enough to understand what's going on. Whether or not the people using the example want to gain access to the message from the server is up to them.
2024-02-14 15:03:40 +00:00

64 lines
1.5 KiB
TypeScript

import type { Comment } from "../interfaces";
import React, { useState } from "react";
import useSWR from "swr";
import { useAuth0 } from "@auth0/auth0-react";
const fetcher = (url) =>
fetch(url).then((res) => {
if (res.ok) {
return res.json();
}
throw new Error(`${res.status} ${res.statusText} while fetching: ${url}`);
});
export default function useComments() {
const { getAccessTokenSilently } = useAuth0();
const [text, setText] = useState("");
const { data: comments, mutate } = useSWR<Comment[]>(
"/api/comment",
fetcher,
{ fallbackData: [] },
);
const onSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const token = await getAccessTokenSilently();
try {
await fetch("/api/comment", {
method: "POST",
body: JSON.stringify({ text }),
headers: {
Authorization: token,
"Content-Type": "application/json",
},
});
setText("");
await mutate();
} catch (err) {
console.log(err);
}
};
const onDelete = async (comment: Comment) => {
const token = await getAccessTokenSilently();
try {
await fetch("/api/comment", {
method: "DELETE",
body: JSON.stringify({ comment }),
headers: {
Authorization: token,
"Content-Type": "application/json",
},
});
await mutate();
} catch (err) {
console.log(err);
}
};
return { text, setText, comments, onSubmit, onDelete };
}