简体   繁体   English

array.map() 无法按预期渲染<li> React 中的组件</li>

[英]array.map() does not work as expected to render <li> component in React

I want to render multiple <li> components using map() function.我想使用 map() function 渲染多个<li>组件。 Nothing is rendered on the screen.屏幕上没有呈现任何内容。 I don't get any error message either, so I have no clue.我也没有收到任何错误消息,所以我不知道。

        reviewCard = reviews.map((review, index) => {
            const url = `http://localhost:3001/users/${review.user_id}`;
            axios
                .get(url)
                .then(response => {
                    return (
                        <li key={index}>
                            <ReviewCard 
                                review={review} 
                                user={response.data}
                            />
                        </li>
                    );
                })
                .catch(error => {
                    console.log(error);
                });
            }
        );

The following code works though.以下代码虽然有效。

        reviewCard = reviews.map((review, index) => (
            <li key={index}>
                <ReviewCard review={review} />
            </li>
        ));

I would appreciate it if you have any suggestion.如果您有任何建议,我将不胜感激。

Thanks:)谢谢:)

You can 1st use promise all to resolve all async code and then map the to create your ReviewCard您可以首先使用 promise all 来解析所有异步代码,然后使用 map 创建您的 ReviewCard

let promiseList = reviews.map((review, index) => {
  const url = `http://localhost:3001/users/${review.user_id}`;
  return axios.get(url);
});

let reviewCard;
Promise.all(promiseList).then((responses) => {
  reviewCard = responses.map((response,index) => {
    return (
      <li key={index}>
        <ReviewCard review={review[index]} user={response.data} />
      </li>
    );
  });
});

Explanation:解释:

  1. Firstly we are creating an array of promises ie your get requests.首先,我们正在创建一系列承诺,即您的获取请求。
  2. Now we resolve all the promises requests using promise.all so that we can finally get an array of responses.现在我们使用 promise.all 解决所有的 Promise 请求,这样我们最终可以得到一个响应数组。
  3. Now we have all sync code so we easily can map the responses array to our ReviewCard.现在我们有了所有同步代码,因此我们可以轻松地将响应数组 map 发送到我们的 ReviewCard。

JSX is not the best place to call some async functions. JSX 不是调用某些异步函数的最佳位置。 Axios then doesn't call rerender of your component. Axios 然后不会调用您的组件的重新渲染。 You have to use useEffect to call axios method and useState for rerender you component and store the results.您必须使用 useEffect 来调用 axios 方法和 useState 来重新渲染您的组件并存储结果。

Just see the next code:只需查看下一个代码:

import React, { useEffect, useState, useCallback } from 'react';

const Cards = ({ reviews }) => {
  const [isLoading, setIsLoading] = useState(true);
  const [users, setUsers] = useState([]); // use state rerender component on each call setUsers;

  const fetchUsers = useCallback(() => {
    try {
      // collect user requests to array
      const listOfRequests = reviews.map((item) => axios.get(`http://localhost:3001/users/${item.user_id}`));
      const responses = await Promise.all(listOfRequests);
      const users = responses.map((item) => item.data);
      setUsers(users);
      setIsLoading(false);
    } catch(error) {
      console.error(error);
      setIsLoading(false);
    }
  }, []);


  useEffect(() => {
    fetchUsers();
  }, []);

  if (isLoading) {
    return <div>Loading...</div>
  }

  if (users.length === 0) {
    return <div>something happens</div>
  }

  return (
    <ul>
      {users.map((user) => <li key={user.id}><Review user={user} /></li>)}
    </ul>
  )
}


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

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