We're going to briefly go over one of the advantages for GraphQL: how it hands over power to each component to request what data they want. And then we're going to see how easy it is to make a GraphQL call in Apollo, with its "useQuery" hook.
Instructor: [0:00] I have a very simple React app here, with this top-level component that prepares some layout, but then just renders this note list component, which is currently empty. Let's build our note-taking app.
[0:12] I'll start by sketching out our state. It's going to be a list of notes. Each note with some content and a category, which will be just an object with a label. In this case, let's say these are some work notes. I'll just duplicate this and change the content a bit.
[0:32] To display these, I'm just going to map each note to this UI note component that I had ready from before. This component just takes in some content and the category label, and then renders the note. Let's see how this all looks in the browser. Awesome! I have some notes.
[0:53] Now, if I'm building an app like Notion, notes will probably get a bit more complicated than this on the backend, with pictures, different note types, and even sub-notes within them. This specific component just wants the content and the category label. It doesn't need anything else. Maybe other components will, but not this one.
[1:13] This is one of the neat parts about GraphQL. Instead of having a single REST call that grabs me all the notes and all their extra info that we don't really need, but we get it just in case something else in the frontend needs it. Maybe the solution is to just have separate calls for different frontend components. A simple one for a component like this, and maybe a full one for other components.
[1:39] Instead of having to worry about all of these, my backend will expose a graph of entities connected in various ways. Then, different components in my frontend can build a GraphQL query and grab whatever they want from it.
[1:55] In this case, I want a list of notes. From each note, give me just the content, the category, and from the category, I just want the label. While I can use the browser's Fetch API to send this to my server, Apollo's client makes this super simple.
[2:14] To set it up, if I go back to my top-level index.js file, I'll first import Apollo Client from the @apollo/client package, and create an instance of it. I'll need to point it to my locally running GraphQL server. Finally, I need to give it an instance of a local cache it can use, which I'll have to import.
[2:37] I also need to import the ApolloProvider component, and then I'll just wrap it around my app. I'm also going to send my newly created client to it as a prop.
[2:48] Back in my component, I'll first need to import the GraphQL tag from the Apollo Client library, wrap it around my query, import the useQuery hook, and then pass it my full GraphQL query. This gives me a result. On that result, there's some data. The format of this data is the format of this query up here. I'm just going to get the list of notes from it.
[3:15] I can remove my mocked list of notes. Instead of this result, I'll just destructure the data directly from it. If I refresh my page, I see some actual notes in here. If I open my Network tab, I see a call made to my GraphQL endpoint with my query sent over. This is the shape of the data I got back.
[3:38] You'll see I get the familiar Reactor in my console, that I'm not adding the key prop to my notes. To fix this, back in my query, I'll request the ID of each note and then I'll just use it as the key prop for each one of my UI note components.
[3:57] Back in the browser, the error just goes away. What's happening here is I'm parsing the string version of my GraphQL query to this GraphQL tag, which is just a function that parses my string and transforms it into an object that Apollo can understand. By the way, if this syntax looks weird, it's called a tagged template literal. It's a JavaScript construct, and it's not related to Apollo.
[4:24] Then, I'm sending my parsed query to the useQuery hook in Apollo, which, because it's part of a component that's an eventual child of the ApolloProvider we just created earlier, it knows which client I'm using, so it knows which server to send the query to. We don't need to keep repeating this in every component from now on.
[4:44] The last thing Apollo does for us, is it makes sure that when that network request comes back and we have some actual values in our data object, it re-renders our component to display the fresh data, something we normally would have had to handle manually using other React hooks, like useState.
[5:02] You can see this. Back in the browser, if we slow down the network and I refresh the page, you'll see the GraphQL query request being invoked. Our screen is blank, we just see the header. When the request finishes, Apollo re-renders our component with all the fresh data.