简体   繁体   English

如何在反应中获取嵌套数据

[英]How to fetch nested data in react

Question regarding fetching nested data in react.关于在反应中获取嵌套数据的问题。

APIs蜜蜂

  1. https://jsonplaceholder.typicode.com/posts https://jsonplaceholder.typicode.com/posts
  2. https://jsonplaceholder.typicode.com/posts/${postId}/comments https://jsonplaceholder.typicode.com/posts/${postId}/comments

Able to fetch list of posts.能够获取帖子列表。 now want to fetch list of comments from when click on post现在想从点击帖子时获取评论列表

here is code so far这是到目前为止的代码

import React, { useEffect, useState } from "react";
import Post from "./Post";

const [posts, setPosts] = useState([]);
const [comments, setComments] = useState([]);

function App() {
  const [posts, setPosts] = useState([]);
  const [comments, setComments] = useState([]);

useEffect(() => {
  const loadposts = async() => {
    const resp = await fetch("https://jsonplaceholder.typicode.com/posts?userId=1");
    const data = await resp.json();
    setPosts(data);
  }
  loadposts();
}, []);

return (
  <div className="App">
    <ul>
      {posts.map((post) => 
      (
        <div>
          <li key={post.id}>
            <Post 
            userId={post.id}
            title={post.title} 
            body={post.body} 
            />
          </li>
      </div>
      ))
      }
    </ul>
  </div>
);
}

export default App;

function Post({title, body, postId}) {
  
  return (
      <div>
          <h5>{postId}</h5>
          <h1>{title}</h1>
          <p>{body}</p>
      </div>
  )
}

export default Post

appreciate any help.感谢任何帮助。 thanks谢谢

Firstly, the "/posts" endpoint returns posts by users, so the query "/posts?userId=1" will return all the posts by user id 1 .首先,“/posts”端点返回用户的帖子,因此查询“/posts?userId=1”将返回用户 id 为1的所有帖子。 You mistakenly passed a userId prop to the Post component instead of the specific post's id , ie您错误地将userId道具传递给Post组件,而不是特定帖子的id ,即

<Post userId={post.id} title={post.title}  body={post.body} />

The React key should also be placed on the outer-most element being mapped, the div in your case, but since li is already a block level element the div is basically extraneous. React 键也应该放在被映射的最外层元素上,在你的例子中是div ,但是由于li已经是一个块级元素,所以div基本上是无关的。

<ul>
  {posts.map((post) => (
    <li key={post.id}> // <-- remove div and place React key on li
      <Post
        postId={post.id} // <-- pass the post's id
        title={post.title}
        body={post.body}
      />
    </li>
  ))}
</ul>

In Post component create a fetch comments utility and click handler, and attach the click handler to the title header.Post组件中创建一个获取评论实用程序和单击处理程序,并将单击处理程序附加到标题 header。 Conditionally render the comments.有条件地呈现评论。 If it wasn't already clear, you'll move the comments state into Posts so each post component maintains its own copy.如果还不清楚,您会将comments state 移动到Posts中,以便每个帖子组件维护自己的副本。 The following is an example for rendering out the comments once fetched, you can use whatever conditional rendering and field subset of your choosing.以下是渲染获取评论的示例,您可以使用您选择的任何条件渲染和字段子集。

const fetchComments = async (postId) => {
  const response = await fetch(
    `https://jsonplaceholder.typicode.com/posts/${postId}/comments`
  );
  return response.json();
};

function Post({ title, body, postId }) {
  const [comments, setComments] = useState([]);

  const clickHandler = () => {
    fetchComments(postId).then(setComments);
  };

  return (
    <div>
      <h5>{postId}</h5>
      <h1 onClick={clickHandler}>{title}</h1>
      <p>{body}</p>
      {comments.length && (
        <>
          Comments:
          <ul>
            {comments.map(({ id, email, name, body }) => (
              <li key={id}>
                <dl>
                  <dt>{email} - {name}</dt>
                  <dd>{body}</dd>
                </dl>
              </li>
            ))}
          </ul>
        </>
      )}
    </div>
  );
}

编辑如何在反应中获取嵌套数据

Working solution if anyone looking for如果有人在寻找工作解决方案


function Post() {
const {id} = useParams();
const [comments, setComments] = useState([]);

useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/posts/${id}/comments`)
    .then((res) => res.json())
    .then(setComments)
    .catch((error) => {
        console.log(error)
    })
    console.log("setComments: ", setComments)
}, [])

    return (
        <div>
            {comments && comments.map((comment) => (
                <div key={comment.id}>
                    <p>{comment.body}</p>
                </div>

            ))}

        </div>
    )
}
export default Post

then update rendering 

    <div className="App">
      <Switch>
     <Route exact path='/'>
        {posts.map((post) => (
         <article key={post.id}> 
          <h1>{post.title}</h1>
            <Link to ={`/${post.id}`}>
              <p>{post.body}</p>
            </Link>
       </article>
      ))}
   </Route>

     <Route path ='/:id'>
        <Post/>
     </Route>
   </Switch>

  </div>

   

    
  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM