Frontend Serverless with React and GraphQL
Start at the beginning and work your way through this project. The code for each step as well as the finished project can be found in the Github repository.
14. Add the RecipeList Component
Objective: Create a Recipes List component which will fetch our list of recipes either from a recipes query or a userLikes query.
The RecipesList component will be responsible for fetching the recipes list data and iterating over the list to display a <p>
tag for each recipe in the list. We will swap out that <p>
tag for a <Recipe />
component in a future lecture.
First, let's install lodash:
bash
npm install --save lodash
Lodash is the swiss army knife of array and object manipulation and we will be using it to fetch values out of our recipes return object.
components/RecipeList.tsx
import { QueryHookOptions, useQuery } from '@apollo/react-hooks';import { recipesGraphQL } from '../graphql/queries/recipes';import { userLikesGraphQL } from '../graphql/queries/userLikes';import * as _ from 'lodash';import { Row } from 'antd';import { Recipe } from '../generated/apollo-components';export enum queryEnum {userLikes = 'userLikes',recipes = 'recipes',}type RecipesListProps = {options?: QueryHookOptions;parentRoute: string;queryType: queryEnum;};export const RecipesList = ({options,parentRoute,queryType,}: RecipesListProps) => {const query =queryType === queryEnum.recipes ? recipesGraphQL : userLikesGraphQL;const { loading, data, error } = useQuery(query, options);const parentArray = _.get(data, queryType);const recipesList = _.map(parentArray, (value) =>_.get(value, 'recipe', value),);console.log(data);console.log(parentArray);if (loading) return <p>Loading</p>;if (error) return <p>Error</p>;if (recipesList.length === 0) return <p>Warning</p>;return (<Row>{recipesList.map((recipe: Recipe) => (<p key={recipe.id}>{recipe.title}</p>))}</Row>);};
We are using the apollo-components
file for our Recipe type definition. We import the recipes and userLikes queries because this list component will allow us to display either recipes or userLikes depending on which queryType
is specified when calling the component.
Now that we have our base <RecipesList />
component, let's turn back to our index.tsx
file in our pages directory. Update the index.tsx
file to import the <RecipesList />
component and also the queryEnum
type.
pages/index.tsx
import styled from 'styled-components';import { MainLayout } from '../components/layout/MainLayout';import { RecipesList, queryEnum } from '../components/RecipesList';const StyledHeader = styled.h1`${({ theme }) => `font-size: 2em;text-align: left;padding: ${theme['padding-small']} ${theme['padding-small']};`}`;const Index = () => {return (<MainLayout title="Recipes"><StyledHeader>Index Page</StyledHeader><RecipesList parentRoute="recipe" queryType={queryEnum.recipes} /></MainLayout>);};export default Index;