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