Fetching Data
Reading
Get a list of restaurants
Looking at GET /api/Restaurants
, we see that this will return a JSON array of
objects where each object represents the details of the sample restaurants we
placed in our database.
We can use this API endpoint to populate the list of restaurants on our home page.
Returning to the UI to populate the list of restaurants
From our statically defined home page, we will extract a component to render the list of restaurants if we haven't already.
That component might look something like this:
function Restaurants() {return (... implementation omitted for space ...)}
Where ...
is the implementation of the listing of restaurants.
Using react-query
In this demonstration, we will use the react-query library to integrate with our backend API.
Before we can begin working with the library, we first need to install it.
From the ClientApp
directory (e.g. where you would run npm start
)
npm install react-query
Configuring react-query
To use the library, we will need to add some configuration to main.tsx
import React from 'react'import ReactDOM from 'react-dom'import './index.scss'import { App } from './App'import { QueryClient, QueryClientProvider } from 'react-query'const queryClient = new QueryClient()ReactDOM.render(<React.StrictMode><QueryClientProvider client={queryClient}><App /></QueryClientProvider></React.StrictMode>,document.getElementById('root'))
Using react-query
to load a list of restaurants
We can now introduce a query to load the list of restaurants.
However, we must first define a TypeScript type
to specify the structure of
the data we'll be receiving from the API.
Open types.ts
and add:
export type RestaurantType = {id?: numbername: stringdescription: stringaddress: stringtelephone: string}
We make the id
optional by adding a trailing ?
to the name of the
property.
This field is optional because we won't always have an id
field. For example,
when creating a new restaurant.
Now in Restaurants.tsx
, we can add:
function Restaurants() {const { data: restaurants = [] } = useQuery<RestaurantType[]>('restaurants',async function () {const response = await fetch('/api/restaurants')return response.json()})console.log({restaurants})return (... implementation omitted for space ...)}
NOTE: In this code
const { data: restaurants = [] } =
we are destructuring the return ofreact-query
to get thedata
property and renaming itrestaurants
. Then with= []
, we are ensuring that ifuseQuery
returns anyrestaurants
that areundefined
then, we will use an empty array.
NOTE: The
console.log({ restaurants })
is a temporary debug statement we use to test that we are correctly loading data from our API
Transform static list into dynamic list
Next, we will change our static list of a few sample restaurants to use
restaurants.map(function(restaurant) {
to generate the list dynamically.
NOTE: we can't yet compute and display the number of stars, so we will leave that hard-coded for now.
function restaurantlist() {const [restaurants, setRestaurants] = useState([])return (...... other content{restaurants.map(function(restaurant) {return (... the code for a single restaurant)))}... other content}
If we have done this successfully, we have a dynamically generated list of restaurants on our home page.
NOTE: We can now remove the
console.log({ restaurants })
since we have confidence the code is working properly.
Files Updated
Refactor
At this point, we can refactor the code for a single restaurant into its own
component. We will put this in a file SingleRestaurantFromList.tsx
, in the
components
directory.
function SingleRestaurantFromList(props) {return (...code for a single restaurant)}function RestaurantList() {... other content ...return (...... other content<ul className="results">{restaurants.map((restaurant) => (<SingleRestaurantFromListkey={restaurant.id}restaurant={restaurant}/>))}</ul>... other content}