Back to blogs
Blog
Writing in public
Longer posts — published here first, then cross-posted to Dev.to with a canonical URL back to this site.
Blog
Longer posts — published here first, then cross-posted to Dev.to with a canonical URL back to this site.
Back to blogs
Back to blogs
Postrelay, react, graphql, vite
relay Relay is a JavaScript framework for fetching and managing GraphQL data in React...
Date published

Why You Might Still Pick Next.js Over TanStack Start From a TanStack Start...

A complete theme management system for React applications with SSR support! ✨ 🌟...

slides used in the presentation building the generic component In this example we'll use...
<script src="https://cdn.tailwindcss.com"></script>
Relay is a JavaScript framework for fetching and managing GraphQL data in React applications that emphasizes maintainability, type safety and runtime performance <br>
<br>
i'd simply summarize it as very opinionated
ideal use cases for relay
1 {!fragData.isLoadingNext &&2 fragData.hasNext ? (3 <button4 className="m-2 hover:text-purple-400 shadow-lg hover:shadow-purple"5 onClick={() => {6 fragData.loadNext(5);7 }}8 >9 --- load more ---10 </button>11 ) : null}12
with only that snippet it'll fetch the next 5 in the list and automatically mereg them to the previous data , if you've worked with // you'll appreciate this simplicity
apollo-clienturqlreact-querySuspense and ErrorBoundary1 const res = await response.json()2 if(!response.ok){3 throw new Error(res.message,res)4 }56 // Get the response as JSON7 return res;
i also added that snippet to throw an error if the status wasn't ok becasuse errors from this specific graphql api were embedded as the response which would cause relay client to error out withut knowing what specific error was returned
usePreloadedQuery which is recomemnded fetch strategy is not supprted in react-router but this can be side sepped by just using uselazyLadedQuery insteadyou can transform your response before it's passed into the provider if you still want to use it with our current data like shown in this tutorial
1VITE_TOKEN = your_personall_access_token
--watch flag were futile so i run npm run relay in another terminal everytime i change the querymy obective with this was to createa a github repository dash board for my github API project , live preview
one of the things i wanted was to list all the branches and list all the cmmits under each branch with pagination on both layers , paginnatating over the first layer worked with react query but the pproblems kept piling and the experience got more inconsistent when trying to do nesetd pagination , apollo wasn't great at it too , Urql was the worst sinceit's pagination strategy was swapping out variables to trigger the re-rener and in all of the above you'd have to merger arrays that are nested almost 3 levels deep that was very inefficient , didn't workas expected so i switched to relay and it fixed that issue remarhably well
Note: in cases like these i'd usually break the query down and execute thechild query in the cild component but in this case this was the query:
1 export const REPOREFS = gql`2 # github graphql query to get more details3 query getRepoRefs(4 $repoowner: String!5 $reponame: String!6 $first: Int7 $after: String8 $firstcommits: Int9 $$aftercommits: String10 ) {11 repository(owner: $repoowner, name: $reponame) {12 nameWithOwner1314 #refs: get branches and all the recent commits to it1516 refs(17 refPrefix: "refs/heads/"18 orderBy: { direction: DESC, field: TAG_COMMIT_DATE }19 first: $first20 after: $after21 ) {22 edges {23 node {24 name25 id26 target {27 ... on Commit {28 history(first: $firstcommits, after: $aftercommits) {29 edges {30 node {31 committedDate32 author {33 name34 email35 }36 message37 url38 pushedDate39 authoredDate40 committedDate41 }42 }43 }44 }45 }46 }47 }48 pageInfo {49 endCursor50 hasNextPage51 hasPreviousPage52 startCursor53 }54 totalCount55 }5657 # end of refs block58 }59 }60 `;61
there was no varaible that i coud pass into the child compnent in order for it to fetch this query in order to query the commits in a child component
the relay alternative looks like this onerepo.tsx
1export const FULLREPO = graphql`23 query onerepoFullRepoQuery(4 $repoowner: String!,5 $reponame: String!,6 ) {7 repository(owner: $repoowner, name: $reponame) {8 nameWithOwner,9 forkCount,10 ...Stars_stargazers11 ...Branches_refs12 # stargazers(after:$after,first:$first) @connection(key: "Stars_stargazers"){13 # ...Stars_stars14 # }15 }16 }17`;
and then every child component only defines a fragement of the main query branches.tsx
1export const Branchesfragment = graphql`2 fragment Branches_refs on Repository3 @argumentDefinitions(4 first: { type: "Int", defaultValue: 3 }5 after: { type: "String" }6 )7 @refetchable(8 queryName: "BranchesPaginationQuery"9 ) {10 refs(11 refPrefix: "refs/heads/"12 orderBy: {13 direction: DESC14 field: TAG_COMMIT_DATE15 }16 first: $first17 after: $after18 ) @connection(key: "Branches_refs",) {19 edges {20 node {21 name22 id23 target {24 ...Commits_history25 }26 }27 }28 }29 }30`;31
1export const CommitsOnBranchFragment = graphql`2 fragment Commits_history on Commit3 @argumentDefinitions(4 first: { type: "Int", defaultValue: 5 }5 after: { type: "String" }6 )7 @refetchable(8 queryName: "CommitsPaginationQuery"9 ) {10 history(first: $first, after: $after)11 @connection(key: "Commits_history") {12 edges {13 node {14 committedDate15 author {16 name17 email18 }19 message20 url21 pushedDate22 authoredDate23 committedDate24 }25 }26 pageInfo {27 endCursor28 hasNextPage29 hasPreviousPage30 startCursor31 }32 totalCount33 }34 }35`;
giving the child compnents relative autonomy and isolating changes and re-renders to the corresponding components
lastly , it (relay-compiler) generates types for you , they have a weird ting with flow in all their examples but it'll gererate typescrit types if you define it in the compiler options in the package.json
1 "relay": {2 "src": "./src",3 "schema": "schema.docs.graphql",4 "language": "typescript",5 "eagerEsModules": true,6 "exclude": [7 "**/node_modules/**",8 "**/__mocks__/**",9 "**/__generated__/**"10 ]11 }
to configure for github graphql api just add your personal access token in the headers and cchange the endpoint

and test out queries , hit ctrl spacebar to get autocomplete and field suggstion.
this package and the compiler rely on babel , i sued vite react fro this projectandit doesn't use babel as the build tool but there's a plugin that helps with that
Also just in case you're building something from the ground up consider a different router
<h3 class="bg-red-400">--- The End ---</h3>