Shuib Abdillahi
Shuib Abdillahi

Reputation: 95

React-Router rendering props

I'm using react router for my project and I need to render separate props (the introduction) to another component which is accessible through my Card component. Currently, each card has a title of a blog, when the "Read more" button is clicked , I want the article page to render showing the introduction for each blog, but nothing is showing.

Blog

import React, {useState,useEffect} from 'react'
import Article from './Article'
import Card from './BlogCards/Card'

function Blog(props) {


    const [blogs, setBlogs] = useState([])
    const [image, setImage] = useState()
    const [selectedBlog, setSelectedBlog] = useState(blogs)

    useEffect(() => {
        fetch("http://cdn.contentful.com...")
        .then(response => response.json())
        .then(data =>
          setBlogs(data.items)
       
        )
      }, []) 

      console.log(blogs)
    return (
        <div className="container">
        {selectedBlog !== null ? blogs.map((blog =>
          <>
          <Card title={blog.fields.title} introduction={blog.fields.introduction} setSelectedBlog={selectedBlog} />
             </>   
        )): 
        
        <Article title={blogs.find(d => d.fields.title === selectedBlog)}   />
        }

        </div>
    )
}

export default Blog

Card

import {Link, Route} from 'react-router-dom'
import Article from '../Article'

function Card(props) {
  
  console.log(props)
    return (
            
            <div className="container">
  <div className="row">
    <div className="col-12">
      <article className="blog-card">
        <div className="blog-card__background">
          <div className="card__background--wrapper">
            <div className="card__background--main" style={{backgroundImage: "url('https://i.pinimg.com/564x/7f/bb/97/7fbb9793b574c32f5d28cae0ea5c557f.jpg')"}}/>
              <div className="card__background--layer"></div>
            </div>
          </div>

        <div className="blog-card__head">
        </div>
        <div className="blog-card__info">
          <h5>{props.title}</h5>
          <p>Lorem ipsum dolor sit, amet consectetur adipisicing elit. Doloremque vero libero voluptatibus earum? Alias dignissimos quo cum, nulla esse facere atque, blanditiis doloribus at sunt quas, repellendus vel? Et, hic!</p>
        <Link to='/article'>
        <button >read more</button>
        </Link>
        </div>
      </article>
    </div>
  </div>
        <Route exact path="/article">
          <Article introduction={props.introduction} />
        </Route>
</div>

    )   
}

export default Card

Article

import React from 'react'
import './Article.css'

function Article(props) {
console.log(props)
    return (
        <div>
             <p>{props.introduction}</p>
        </div>
    )
}

export default Article

This his how my routes are set up:

<Route path='/blog'>
 <Blog />
</Route> 
<Route path='/article'>
  <Article />
</Route> 

Upvotes: 1

Views: 262

Answers (1)

Drew Reese
Drew Reese

Reputation: 202605

Issue

The introduction prop isn't passed to the Article component rendered by the Route in your main router in App.

<Route path='/article'>
  <Article /> // <-- no extra props
</Route>

You are rendering a second route within the Card component that will never match because the Card is rendered by Blog which is rendered on the path='/blog' path, so "/article" won't ever match (especially "exactly").

Solution

A simple solution would be to send a specific introduction in route state for the transition to the "/article" path.

Update the link in Card component to send the title and introduction in route state.

<Link
  to={{
    pathname: '/article',
    state: {
      title: props.title,
      introduction: props.introduction
    }
  }}
>
  <button>read more</button>
</Link>

Remove the extraneous <Route exact path="/article"> from Card.

Unless you have two different Article components, you likely want to remove the other Article component from Blog that a title prop is passed to and let the main router render the article.

In Article use the useLocation React hook to access the route state.

import { useLocation } from 'react-router-dom';

function Article(props) {
  const { state = {} } = useLocation();

  return (
    <div>
      <p>{state.introduction}</p>
    </div>
  )
}

Upvotes: 1

Related Questions