I want to GET data from two different end points but render them in the same component. I want to use React hooks to do it as well.
Here is what the useEffect/useState looks like (I know I have redundant code here - I've been trying different ways):
const [user, setUser] = useState([])
const [post, setPost] = useState([])
const [data, setData] = useState({post: [], user: []})
const [queriedProducts, setQueriedProducts] = useState([])
useEffect(() => {
const fetchData = async () => {
const userResp = await axios.get("https://jsonplaceholder.typicode.com/users");
const postResp = await axios.get("https://jsonplaceholder.typicode.com/posts");
setData({post: postResp.data, user: userResp.data})
setUser(userResp.data)
setPost(postResp.data)
console.log(user, post)
console.log(userResp.data, postResp.data)
}
fetchData()
}, [])
I want to render the author's name (one endpoint) under the title (other endpoint). My .map works for rendering the posts. I'm stuck at getting the author in there too.
return (
<div id="main-box">
<Search onSubmit={handleSubmit} onChange={handleSearch} />
{post.map((post, index) => index < 10 ?
<Post
title={post.title}
name={user.name}
body={post.body}
id={post.id}
index={index}
/>
: null
)}
<button id="load-btn" onClick={handleClick}>Load more</button>
</div>
)
I have been looking on SO for around an hour and found some things about api calls but not from two different end points. The redundant useStates are from that investigation. Thanks in advance!
CodePudding user response:
You have a couple issues that you will eventually discover. Built a small sample of a better setup.
Codesandbox ref: https://codesandbox.io/s/axiosquery-yl0mi
List.jsx
import axios from "axios";
import { useEffect, useMemo, useState } from "react";
import { Post } from "./Post";
export function List() {
const [{ posts, users }, setData] = useState({ post: [], user: [] });
useEffect(() => {
const fetchData = async () => {
const userResp = await axios.get(
"https://jsonplaceholder.typicode.com/users",
);
const postResp = await axios.get(
"https://jsonplaceholder.typicode.com/posts",
);
setData({ posts: postResp.data, users: userResp.data });
};
fetchData();
}, []);
const filteredPosts = useMemo(() => {
const filteredPosts = [];
if (posts)
for (let i = 0; i < posts.length && i < 10; i ) {
filteredPosts.push(posts[i]);
}
return filteredPosts;
}, [posts]);
return (
<div id="main-box">
{/* <Search onSubmit={handleSubmit} onChange={handleSearch} /> */}
{filteredPosts.map((post, index) => (
<Post post={post} users={users} key={post.id} />
))}
{/* <button id="load-btn" onClick={handleClick}>Load more</button> */}
</div>
);
}
Post.jsx
import { useMemo } from "react";
import { User } from "./User";
export function Post({ post: { title, body, userId }, users }) {
const user = useMemo(() => users.find(({ id }) => id === userId), [
users,
userId,
]);
return (
<div>
<h3>Title: {title}</h3>
<p>Body: {body}</p>
<User user={user} />
</div>
);
}
User.jsx
export function User({ user: { name, username } }) {
return (
<div>
<h4>{name}</h4>
<h5>{username}</h5>
</div>
);
}
CodePudding user response:
You need to find the user "author" of each post.
Try with this:
{post.map((post, index) => index < 10
? <Post
title={post.title}
name={user.find(u => u.id === post.userId).name}
body={post.body}
id={post.id}
index={index}
/>
: null
)}