Reactjs: On clicking title display blog post contents

Viewed 570

I'm trying to make a blogsite using MERN stack. So here I have my Blogs component which fetches all blogposts from db and display as shown below

enter image description here

here's the react code for the above pic

import { useEffect, useState } from "react";
import axios from 'axios';
import BlogDetails from "./BlogDetails";

const Blogs = () => {
    const [blogPost, setPosts] = useState([])
    useEffect(()=>{
     const fetchBlog = async ()=>{
      const blogsData = await axios('http://localhost:4000/blogs')
      const blogsFetched = blogsData.data
      console.log(blogsFetched);
      setPosts(blogsFetched)
     }
     fetchBlog()   
    },[])
    return ( 
        <div className="blogs content">
          <h2>All Blogs</h2>
          { blogPost.map((post)=>(
            <div key={post._id}>
              <a className="single" href={post._id}>
              <h3 className="title" >{post.title}</h3>
              <p className="snippet">{post.snippet}</p>
              </a>
            </div>
          ))
          }
        </div>
    );
}
 
export default Blogs;

I want to show a particular blog post in detail when I click on its title from the above page. On clicking the title, those details will be passed as props to another component named BlogDetails and will be rendered. The part where I'm stuck is routing to BlogDetails component with blogpost id. Is there any way in which on clicking the title, I can use Route to render BlogDetails component?
Please help

2 Answers

Assuming you're using react-router, you could do something like:

const history = useHistory();
.
.
.
<div onClick={() => history.push(`/blog/${post.id}`)}>
  <h3 className="title">{post.title}</h3>
</div>

And then your router will render your component which you specified to be rendered for the /blog route. In that route, you can fetch the url using useLocation and then parse the id by splitting the url.

const { pathName } = useLocation(); // also from react-router

Alternatively (and more elegantly), you can push pieces of state when you do history.push, like:

...onClick={() => history.push(`/blog${post.id}`, { blogId: ${post.id}})}

Then again in your subsequently rendered component you use useLocation to get the state passed:

const { state } = useLocation();

yes you can use route for BlogDetail component

add BlogDetail link in BrowserRouter

<Route path={'url'} render={(props) => <BlogDetail/>}/>

In Blogs component use Link of react router dom and then use this link on title in render html like this

import { Link } from "react-router-dom";

 { blogPost.map((post)=>(
            <div key={post._id}>
              <a className="single" href={post._id}>
              
              <Link to={{
                    pathname:'url', // this will be your url of BlogDetail
                    state: post //if you want post object detail in next component
              }}>
                 <h3 className="title" >{post.title}</h3>
               </Link>
              <p className="snippet">{post.snippet}</p>
              </a>
            </div>
          ))
          }
Related