We'll refactor the Story out to a separate component, create a fragment for the story fields and reuse the fragment in the bookmarks query.
We'll see how using Fragments makes it easy to query for data throughout our application.
Instructor: [0:00] Let's add a new folder to the source directory, and let's call it Components. In components, let's add a new file called story.tsx. Here, let's import star as react from React and export const story.
[0:16] This is a React functional component returning an error function and let's return null for now. In our screens directory, let's open the home screen and scroll down to the render item. Let's copy everything the render item returns and paste it into our story component.
[0:35] We'll need to import pressable and text from React Native. Let's copy the useNavigation hook from the home screen and also the imports. We'll also need the title and the summary style. From home, scroll down to the styles.
[0:52] Let's just copy all of them and just keep the summary and the title. We'll also need to import style sheet from React Native.
[1:00] This story item will need to be passed down as props to the component. The question is, what's the best way to type this? In our GraphQL directory, let's create a new file called Fragments. Fragments in GraphQL allow you to create reusable snippets of queries.
[1:16] Let's import the GraphQL tag from Urql. Let's export const story summary fields, and this will be wrapped in a GraphQL tag. In template strings, let's do fragment story summary fields on story, and let's query for ID, title, and summary.
[1:38] These are the fields that we queried for the old stories. The way you declare a fragment is you start with the fragment keyword. Then you give the fragment a name, in our case, the story summary fields. Then you use the on-keyword, you'll say what data type this fragment is on.
[1:55] In this case, this is a fragment on the story. If we go into Insomnia and into our schema explorer, we will see on the query, stories will return a list of story types. A fragment on a story will need to include a subset of fields from the available fields of the story type.
[2:19] In our home screen, let's import the story summary field fragment we just created, and let's include it in the bottom of our GraphQL query. Including it here, the user will be able to use this fragment inside our query. We use it by copying the name of the fragment.
[2:36] In stories, we had previously listed out each of the fields. We instead spread out the story summary fields. Now let's open a terminal and run yarn generate GraphQL types.
[2:48] Let's look at what this generated. In our generated operation types file, we find that we now have a type for the story summary fields fragment, which is exactly what we want to use in our story component.
[2:59] Let's import the story summary fields fragment from our generated operation types. Let's use it to type our react component. We'll do item, and this will be of type story summary fields fragment. In our home screen, let's import story from component's story.
[3:15] Let's scroll down to the render item in our flat list. Let's replace the pressable with the reusable story component. We'll need to pass in item as the prop for the story. We no longer need the summary and the title styles.
[3:30] We can also delete the navigation hook and the unused imports. In the bookmark screen, let's import the GraphQL tag from Urql. In Insomnia, let's copy our all bookmarks query. In the bookmark screen, we'll do const bookmarks query = GraphQL tag, template literals.
[3:48] Let's paste the query. This query queries the bookmarks and the bookmarks have an ID and a story. If we look at the GraphQL schema, we can see that our bookmarks return an ID and a story. A story is of type story, meaning that we can reuse the fragment we created earlier.
[4:06] Import the story summary fields from fragments. Let's add it underneath our query within the GraphQL tags. Similar to the home page query, we'll need to spread the fields underneath story.
[4:18] Now that we finished building our bookmarks query, let's open a terminal and generate the types. I'm currently getting an ESLint error because while linting this operation types file, we're actually linting the whole code base. This bookmarks query hasn't been used yet.
[4:31] Open the package JSON and rename lint fix to lint fix types. We'll need to update the name in the script as well. Instead of running yarn lint, which calls ESLint on the whole code base, let's copy the relative path for the operation types, and change yarn lint to ESLint and a path we copied, --fix.
[4:51] Opening the terminal again and re-running the query, it will only type the file we generated. Opening operation types, we'll see we have a new query here called All Bookmarks Query.
[5:00] In our bookmarks screen, import useQuery from Urql, and the All Bookmarks Query and All Bookmarks Query variables from our generated types. In screen component, we'll do const array = useQuery.
[5:15] We'll pass in an object with the query being the bookmarks query we just created. This will return an array with an object that we can immediately de-structure to be data, error, and fetching. In our useQuery, pass in the All Bookmarks Query and the All Bookmarks Query variables. From the home screen, we can copy the if-fetching and if-error returns, and paste it into our bookmarks screen underneath the useQuery hook.
[5:42] Remember to import activity indicator from React Native back to the home screen. Let's also copy the flat list and paste it into the end of the bookmark screen. We'll need to import flat list from React Native. We also have three styles for the flat list container, flat list, and separator.
[5:59] From the home screen, let's copy these three styles and paste it to the bookmark stylesheet. Because we've typed this query, Typescript will tell us that data.stories doesn't exist. Let's delete this. We'll see that instead we get data.bookmarks.
[6:14] In the render item, we're returning a story. First, let's import story from the components directory. Typescript is telling us that this item is incorrect. Sure enough, the type of this item is bookmark and the story is actually a field in bookmark.
[6:30] Rather than passing in the item, we pass in item.story. Because we use the same fragment in the old bookmarks query, as we did in the old stories query, we now have confidence that this story component will always get the correct fields.
[6:46] If we open the bookmarks tab, we will see our loading screen followed by the bookmarks loading in.