In this section of the tutorial you’ll implement the voting feature! Authenticated users are allowed to submit a vote for a link. The most upvoted links will later be displayed on a separate route!
Once more, let’s first prepare the app’s components before implementing the actual upvote mutation. There’s several things that the
Link component isn’t currently displaying, compared to the real Hackernews site.
Before you’ll modify the
Link component, let’s write a function that takes a timestamp and converts it to a string that’s more user friendly, e.g.
"3 hours ago".
Now, let’s update the
Link component with everything that is has previously been missing!
As you can see, we’ve also added a new prop. Each
Link element will also render its position inside the list, so you have to now pass it the
index prop from the
Notice that the app won’t run at the moment since the
votes are not yet included in the query. You’ll fix that next!
All you do here is include information about the user who posted a link as well as information about each link’s votes in the query’s payload. You can now run the app again and the links will be ddisplayed properly.
Note: If you’re not able to fetch the links, restart the server and reload the browser. You could also check if everything is working as expected on
Let’s now move on and implement the
When you’ve updated the
Link component you also added an empty
upvote handler. Let’s now add the mutation and populate that handler with the usual logic, like you did back for the
Login component in a previous step.
This step should feel pretty familiar by now. You’re adding the new mutation inside of your component by adding the
useMutation hook. You’re also passing the
linkId variable to
executeMutation, since it’s required by the
You can now go ahead and test this! Run
yarn start in
hackernews-react-urql, make sure that you’re logged in, then click the upvote button on a link. You should then see the link’s upvote number update automagically!
Remember: We haven’t set up any configuration for
@urql/exchange-graphcacheyet, but since it’s a normalized cache, it knows that the link it receives back from the mutation needs to also be updated on the feed query!
Next up, you’ll add a search page to your app!
The search will be available under a new route and allow you to filter all links that have been submitted to your GraphQL API.
Again, this is a pretty standard setup. You’re rendering an
input field where the user can type a search string.
It’s worth noting that this time we’d like to start the search imperatively. Instead of the
useQuery hook starting the search immediately while the user is typing, we’d like to only start searching once the user clicks the “search” button.
For now the
search handler and
links array are also empty stubs, but we’ll be replacing them in a later step.
Let’s also add a button to the header so users can comfortably navigate to the search page.
You can now navigate to the search feature using the “search” button in the
Great, let’s now go back to the
Search component and implement the actual search!
This query looks similar to the feed query that’s used in
LinkList. However, this time it takes in an argument called
filter that will be used to constrain the list of links you want to retrieve.
Previously you’ve always just passed
useQuery a query and some variables. But in the case of the new
Search component, the query is meant to run programmatically, when the “search” button is clicked. You can utilise the
executeQuery method and the
pause argument to achieve this.
LinkList you’re passing the query and variables arguments to
useQuery. But instead of immediately running the query, the
pause option is now set to
true. This flag will cause
useQuery to wait until
executeQuery is programmatically called.
This is a very powerful option as you could also flip
false at any time to let the hook start the query automatically. This is essentially one of the use-cases of having
executeQuery! You can call it programmatically to ask for new results or use it in combination with
pause: true to make it behave like the
Go ahead and test the app by running
yarn start in a terminal and navigating to
http://localhost:3000/search. Then type a search string into the text field, submit the search, and verify that the links that are being displayed were filtered by your search string.