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;