Home > Net >  React hooks .map over two different api calls
React hooks .map over two different api calls

Time:12-15

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 
)}
  • Related