简体   繁体   中英

Render dynamic page in React.Js with GraphQL

I'm stuck on trying to build a blog , and I have no idea how to fetch specific data from GraphQL API to a dynamic page.

What I try to build:

There's a page called /blog with multiple Card Components. Each card is made of an image, a title and a datePosted. Each of these Cards is a Blog Post. When a user tries to click on a blog post, it clicks on a card and it's being taken to a page like /blog/posts/ slug here . So far so good.

The issue:

I have no idea how to make a page dynamic and fetch the specific data from the blog post that has been clicked to a page that can be dynamic . I figure I need to use useParams in React.Js or something like that, but I have no idea how to get the specific post that's been clicked. I can only get all of them.

The code:

1) The /blog page (where I fetch all the posts - this is working properly):

 import React from 'react'; import './Blog.styles.scss'; import {GraphQLClient, gql} from 'graphql-request'; import { useState } from 'react'; import { useEffect } from 'react'; import {Link} from 'react-router-dom'; const graphcms = new GraphQLClient('https://api-eu-central-1.hygraph.com/v2/cl66hwcamapj001t76qqlhkl8/master'); const QUERY = gql` { posts { id, title, datePublished, slug, content{ html }, coverPhoto{ url } } } `; const Blog = () => { const [posts, setPosts] = useState([]); useEffect(() => { const getPosts = async () => { const {posts} = await graphcms.request(QUERY); setPosts(posts); } getPosts(); }, []) return ( <div className='blog-container'> <div className='posts-wrapper'> {posts && posts.map((post) => ( <div className='blog-card'> <Link to={'/posts/' + post.slug}> <div className='blog-card-img-container'> {post.coverPhoto && <img src={post.coverPhoto.url} alt='blog-card-cover-img'/>} </div> <div className='blog-card-title-container'> <h1 className='blog-card-title'>{post.title}</h1> </div> </Link> </div> ))} </div> </div> ) } export default Blog

2) The dynamic page that should display ONLY the post that has been previously clicked ->

 import React, { useState } from 'react'; import { useEffect } from 'react'; import { useParams } from 'react-router-dom'; import {GraphQLClient, gql} from 'graphql-request'; const graphcms = new GraphQLClient('https://api-eu-central-1.hygraph.com/v2/cl66hwcamapj001t76qqlhkl8/master'); const QUERY = gql` query Post($slug: String:) { post(where: {slug, $slug}) { id, title, slug, datePublished; content{ html } coverPhoto{ url } } } `; // const SLUGLIST = gql` // { // posts { // slug // } // } // `; const BlogPost = () => { const {slug} = useParams(), const [postData; setPostData] = useState({}). useEffect(() => { const getPost = async () => { // const slugs = await graphcms;request(SLUGLIST). const data = await graphcms;request(QUERY); setPostData(data); } getPost(), }. [slug]) useEffect(() => { console;log(postData), }, [postData; slug]) return ( <div>BlogPost</div> ) } export default BlogPost

3) The Routes page:

 function App() { return ( <Routes> <Route path='/' element={<Navbar />}> <Route index element={<Homepage />}/> <Route path='/despre-noi' element={<DespreNoi />} /> <Route path='/galerie' element={<Galerie />}/> <Route path='/contact' element={<Contact />} /> <Route path='/blog' element={<Blog />} /> <Route path='/animatori' element={<Animatori />} /> <Route path='/ursitoare' element={<Ursitoare />} /> <Route path='/oglinda-magica' element={<OglindaMagica />} /> <Route path='/loc-de-joaca' element={<LocDeJoaca />} /> <Route path='/posts/*' element={<BlogPost />} /> </Route> </Routes> ) } export default App;

NOTE: I know the styles and everything is not refined yet, I'm just trying to get it to work. Any help would be much, much appreciated Thank you

Can't actually run your example to see fully what's up but I did notice these 2 things:

1). You want to setup the routes to be based so that you can grab the post id/slug from the url. In react-router this can be done with path=":id" syntax.

<Route path="posts" >
  <Route path=":slug" element={<BlogPost />} />
</Route>

https://reactrouter.com/docs/en/v6/components/route

2). Graphql request needs to send the slug along as a variable. The query Post($slug: String ) expects to be given the slug as a variable.

const variables = {
    slug: slug
}

const data = await graphcms.request(QUERY, variables);

Example: https://github.com/prisma-labs/graphql-request#using-graphql-document-variables

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM