The cool thing about Next.js API routes is that we can directly consume the API endpoints from pages.
SWR is a nice tool for handling data loading state in React apps using hooks, and is a perfect companion for our Next.js application. In this lesson, we will learn how to use SWR - a data fetching library by Zeit - to consume API endpoints on the client-side, and conditionally render an error or a loading component when the data is not available.
pages/api/user/[id].ts:
import { NextApiHandler } from "next";
const data = [
{ id: 1, name: "Wan" },
{ id: 2, name: "Zhen" },
{ id: 3, name: "Tian" }
];
const user: NextApiHandler = (req, res) => {
const { id } = req.query;
const userData = data.find(x => String(x.id) === String(id));
if (userData) {
res.status(200).json(userData);
} else {
res.status(404).end();
}
};
export default user;
pages/user/[id].tsx:
import { useRouter } from "next/router";
import { SimpleGrid, Text, Alert, Flex, Heading } from "@chakra-ui/core";
import useSWR from "swr";
const fetcher = async (url: string) => {
const res = await fetch(url);
if (!res.ok) {
throw Error("Yo that's NOT OK!!!");
}
const data: {
id: string;
name: string;
email: string;
} = await res.json();
return data;
};
const UserData = () => {
const router = useRouter();
const { id } = router.query;
const { data, error } = useSWR(`/api/user/${id}`, fetcher);
if (error) {
return <Alert status="error">Loading fail</Alert>;
}
if (!data) {
return <Alert status="info">Loading...</Alert>;
}
return (
<SimpleGrid columns={2} width="2xs" spacingY={4}>
<Text fontWeight="bold" marginRight={4}>
UserID
</Text>
<Text>{data.id}</Text>
<Text fontWeight="bold" marginRight={4}>
Name
</Text>
<Text>{data.name}</Text>
<Text fontWeight="bold" marginRight={4}>
Email
</Text>
<Text>{data.email}</Text>
</SimpleGrid>
);
};
const user = () => {
return (
<Flex flexDirection="column" alignItems="center">
<Heading as="h1">User</Heading>
<UserData />
</Flex>
);
};
export default user;