Link 在反应中单 post
Link to single post in react
@编辑
好的,所以我在主应用程序中更新我的代码:
function App() {
return (
<Layout>
<Switch>
<Route path='/' exact={true}>
<Posts />
</Route>
<Route path='/favorite-posts'>
<FavoritePosts />
</Route>
<Route path='/single-post:id'>
<SinglePost />
</Route>
<Route>
<Page404 path='*' />
</Route>
</Switch>
</Layout>
)
}
看起来页面正在运行,但我如何将标题和 body 从 fetch 传递到 SinglePage?
const Posts = () => {
const [data, setData] = useState([])
const [isLoading, setIsLoading] = useState(true)
useEffect(() => {
fetchData()
}, [])
// useEffect(() => {
// fetchImg()
// }, [])
const fetchData = async () => {
let response = await fetch('https://jsonplaceholder.typicode.com/posts')
await response
.json()
.then((finish) => {
setIsLoading(false)
setData(finish) //.splice(0, 5)
console.log(finish)
})
.catch((error) => {
console.error('Houston, we have a problem.. with fetch')
})
}
//loading animation
if (isLoading) {
return <Loading />
}
return (
<>
<BlogPosts datas={data} />
</>
)
}
export default Posts
const Post = ({ title, body, random, id }) => {
const favoritesCtx = useContext(FavoritesContext)
const itemIsFavorite = favoritesCtx.itemIsFavorite(id)
function toggleFavoriteStatusHandler() {
if (itemIsFavorite) {
favoritesCtx.removeFavorite(id)
} else {
favoritesCtx.addFavorite({
id: id,
title: title,
body: body,
})
}
}
return (
<article className={styles.box}>
<Link to={`/single-post:${id}`}>
<img
className={styles.box__image}
// src={`https://rickandmortyapi.com/api/character/avatar/${random}.jpeg`}
src={`https://rickandmortyapi.com/api/character/avatar/19.jpeg`}
alt='test'
/>
</Link>
<button
className={itemIsFavorite ? styles.box__btn_two : styles.box__btn}
onClick={toggleFavoriteStatusHandler}
>
{itemIsFavorite ? 'Remove from Favorites' : 'Add to Favorites'}
</button>
<h4 className={styles.box__title}>{title}</h4>
</article>
)
}
const SinglePost = ({ title, body, id }) => {
return (
<section>
<p>{id}</p>
<h1>{title}</h1>
<h2>{body}</h2>
<p>hey</p>
</section>
)
}
export default SinglePost
我从 https://jsonplaceholder.typicode.com/posts
获取并映射 posts
我的网站上已经有 post,但是我怎样才能转到单个 post 并获得独特的信息我的意思是 body 和 post 的标题?
知道我该怎么做吗?
将此添加到您的路线
<Route path='/post:id'>
<Post />
</Route>
并将 Link 添加到您的 Post 组件以重定向
<Link to={"/post"+{item._id}/>
您需要为此做一些调整。如果您希望每个 post 都有一个专用页面,那么 SinglePost
将作为一个页面。
您必须添加一个路由,该路由接受 post id 作为参数,并在此基础上获取特定 post 的数据并呈现该组件。像这样:
<Switch>
//...
<Route path='/post/:id'>
<SinglePost />
</Route>
//...
</Switch>
现在在 SinglePost
文件中,从路由参数中获取 ID,然后进行 api 调用。
import {useParams, useState, useEffect} from 'react'
const SinglePost = (props) => {
//this is where we will store data after getting from api
const [post, setPost] = useState();
// get id from route param using this hook
const id = useParams().id;
// then in useEffect call the api to fetch data for single post
useEffect(()=>{
axios.get(`https://jsonplaceholder.typicode.com/posts/${id}`).then(res => {
setPost(res.data);
})
},[])
return (
<section>
<h1>{post?.title}</h1>
<h2>{post?.body}</h2>
</section>
)
}
export default SinglePost;
希望你能拍到照片。
好的,我做到了!
import { useLocation } from 'react-router'
import { useEffect, useState } from 'react'
import styles from './SinglePost.module.css'
import Loading from '../ui/Loading'
import Comments from './Comments'
const SinglePost = () => {
const location = useLocation()
const path = location.pathname.split('/')[2]
const [data, setData] = useState([])
const [isLoading, setIsLoading] = useState(true)
const [comm, setComm] = useState([])
useEffect(() => {
fetchData()
}, [])
useEffect(() => {
fetchComment()
}, [])
const fetchData = async () => {
let response = await fetch(
'https://jsonplaceholder.typicode.com/posts/' + path
)
await response.json().then((finish) => {
setIsLoading(false)
setData(finish)
console.log(finish)
})
}
const fetchComment = async () => {
let response = await fetch('https://jsonplaceholder.typicode.com/comments/')
await response.json().then((finish) => {
setIsLoading(false)
setComm(finish.splice(0, 7)) //random
console.log(finish)
})
}
if (isLoading) {
return <Loading />
}
return (
<section className={styles.single}>
<div className={styles.single__text}>
<h1>{data.title}</h1>
<p>{data.body}</p>
<h4>Comments:</h4>
</div>
<div className={styles.comments}>
{comm.map((comme) => {
return (
<Comments
key={comme.id}
name={comme.name}
email={comme.email}
body={comme.body}
/>
)
})}
</div>
</section>
)
}
export default SinglePost
@编辑 好的,所以我在主应用程序中更新我的代码:
function App() {
return (
<Layout>
<Switch>
<Route path='/' exact={true}>
<Posts />
</Route>
<Route path='/favorite-posts'>
<FavoritePosts />
</Route>
<Route path='/single-post:id'>
<SinglePost />
</Route>
<Route>
<Page404 path='*' />
</Route>
</Switch>
</Layout>
)
}
看起来页面正在运行,但我如何将标题和 body 从 fetch 传递到 SinglePage?
const Posts = () => {
const [data, setData] = useState([])
const [isLoading, setIsLoading] = useState(true)
useEffect(() => {
fetchData()
}, [])
// useEffect(() => {
// fetchImg()
// }, [])
const fetchData = async () => {
let response = await fetch('https://jsonplaceholder.typicode.com/posts')
await response
.json()
.then((finish) => {
setIsLoading(false)
setData(finish) //.splice(0, 5)
console.log(finish)
})
.catch((error) => {
console.error('Houston, we have a problem.. with fetch')
})
}
//loading animation
if (isLoading) {
return <Loading />
}
return (
<>
<BlogPosts datas={data} />
</>
)
}
export default Posts
const Post = ({ title, body, random, id }) => {
const favoritesCtx = useContext(FavoritesContext)
const itemIsFavorite = favoritesCtx.itemIsFavorite(id)
function toggleFavoriteStatusHandler() {
if (itemIsFavorite) {
favoritesCtx.removeFavorite(id)
} else {
favoritesCtx.addFavorite({
id: id,
title: title,
body: body,
})
}
}
return (
<article className={styles.box}>
<Link to={`/single-post:${id}`}>
<img
className={styles.box__image}
// src={`https://rickandmortyapi.com/api/character/avatar/${random}.jpeg`}
src={`https://rickandmortyapi.com/api/character/avatar/19.jpeg`}
alt='test'
/>
</Link>
<button
className={itemIsFavorite ? styles.box__btn_two : styles.box__btn}
onClick={toggleFavoriteStatusHandler}
>
{itemIsFavorite ? 'Remove from Favorites' : 'Add to Favorites'}
</button>
<h4 className={styles.box__title}>{title}</h4>
</article>
)
}
const SinglePost = ({ title, body, id }) => {
return (
<section>
<p>{id}</p>
<h1>{title}</h1>
<h2>{body}</h2>
<p>hey</p>
</section>
)
}
export default SinglePost
我从 https://jsonplaceholder.typicode.com/posts
获取并映射 posts我的网站上已经有 post,但是我怎样才能转到单个 post 并获得独特的信息我的意思是 body 和 post 的标题?
知道我该怎么做吗?
将此添加到您的路线
<Route path='/post:id'>
<Post />
</Route>
并将 Link 添加到您的 Post 组件以重定向
<Link to={"/post"+{item._id}/>
您需要为此做一些调整。如果您希望每个 post 都有一个专用页面,那么 SinglePost
将作为一个页面。
您必须添加一个路由,该路由接受 post id 作为参数,并在此基础上获取特定 post 的数据并呈现该组件。像这样:
<Switch>
//...
<Route path='/post/:id'>
<SinglePost />
</Route>
//...
</Switch>
现在在 SinglePost
文件中,从路由参数中获取 ID,然后进行 api 调用。
import {useParams, useState, useEffect} from 'react'
const SinglePost = (props) => {
//this is where we will store data after getting from api
const [post, setPost] = useState();
// get id from route param using this hook
const id = useParams().id;
// then in useEffect call the api to fetch data for single post
useEffect(()=>{
axios.get(`https://jsonplaceholder.typicode.com/posts/${id}`).then(res => {
setPost(res.data);
})
},[])
return (
<section>
<h1>{post?.title}</h1>
<h2>{post?.body}</h2>
</section>
)
}
export default SinglePost;
希望你能拍到照片。
好的,我做到了!
import { useLocation } from 'react-router'
import { useEffect, useState } from 'react'
import styles from './SinglePost.module.css'
import Loading from '../ui/Loading'
import Comments from './Comments'
const SinglePost = () => {
const location = useLocation()
const path = location.pathname.split('/')[2]
const [data, setData] = useState([])
const [isLoading, setIsLoading] = useState(true)
const [comm, setComm] = useState([])
useEffect(() => {
fetchData()
}, [])
useEffect(() => {
fetchComment()
}, [])
const fetchData = async () => {
let response = await fetch(
'https://jsonplaceholder.typicode.com/posts/' + path
)
await response.json().then((finish) => {
setIsLoading(false)
setData(finish)
console.log(finish)
})
}
const fetchComment = async () => {
let response = await fetch('https://jsonplaceholder.typicode.com/comments/')
await response.json().then((finish) => {
setIsLoading(false)
setComm(finish.splice(0, 7)) //random
console.log(finish)
})
}
if (isLoading) {
return <Loading />
}
return (
<section className={styles.single}>
<div className={styles.single__text}>
<h1>{data.title}</h1>
<p>{data.body}</p>
<h4>Comments:</h4>
</div>
<div className={styles.comments}>
{comm.map((comme) => {
return (
<Comments
key={comme.id}
name={comme.name}
email={comme.email}
body={comme.body}
/>
)
})}
</div>
</section>
)
}
export default SinglePost