Reputation: 95
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
Reputation: 202605
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").
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