首页 > 解决方案 > React 不渲染 Axios 调用的 map 函数

问题描述

我正在尝试制作一个购物车表,其中显示图像、产品名称和删除按钮。我从 localStorage 中获取了每个产品的 id,并使用 Axios.get(by id) 调用该 id 的所有数据。

我创建了一个表格来显示产品的价格、图片和名称,但是我的 .map 函数没有在网站中显示信息(即使我可以通过 console.log 看到它)。这是代码:

import Axios from "axios";
import React from "react";

function ClientCardBlock() {
  let memory = window.JSON.parse(localStorage.getItem("toy"));
  console.log(memory); **this log shows me that all the IDs are now in an array**

  const renderItems = () => {
    memory.map(
      async (toy_id) =>
        await Axios.get(`http://************/${toy_id}`).then(
          (response) => {
            const toy = response.data;
            console.log(toy.price); **this log show me the price of each toy, so it's working**
            return (
              <tr key={toy._id}>
                <th>
                  <img
                    alt=""
                    className="card-img-top embed-responsive-item"
                    src={`http://*********/${toy.images}`}
                  />
                </th>
                <th>$ {toy.price}</th>
                <th>
                  <button>Remove</button>
                </th>
              </tr>
            );
          }
        )
    );
  };

  return (
    <div>
      <table className="table table-bordered">
        <thead>
          <tr>
            <th scope="col">Image product</th>
            <th scope="col">Product</th>
            <th scope="col">Remove</th>
          </tr>
        </thead>
        <thead>{renderItems()}</thead>
      </table>
    </div>
  );
}

export default ClientCardBlock;

https://imgur.com/a/bthMJN4

标签: javascriptreactjs

解决方案


通常你可以改变它,使 renderItems 成为一个功能组件。

function RenderItems() {
  return memory.map...(etc)
}

...

<thead><RenderItems /></thead>

但由于这是一个异步函数,因此您需要使用 useEffect。这个 useEffect 获取数据并将其保存到您的组件状态中。然后一旦它存在,它将在稍后呈现。关键点是将提取与渲染分开。

function ClientCardBlock() {
  const [data, setData] = useState([]);

  useEffect(() => {
    /* this runs on component mount */
    const memory = window.JSON.parse(localStorage.getItem("toy"));

    Promise.all(memory.map((toy_id) => Axios
                .get(`http://************/${toy_id}`)
                .then((response) => response.data)))
                /* Wait on the Promise.All */
                .then(newData => {
                  /* Set the data locally */
                  setData(newData);
                });
  }, []);

  return (
    <div>
      <table className="table table-bordered">
        <thead>
          <tr>
            <th scope="col">Image product</th>
            <th scope="col">Product</th>
            <th scope="col">Remove</th>
          </tr>
        </thead>
        <thead>
          {data.map(toy => (
              <tr key={toy._id}>
                <th>
                  <img
                    alt=""
                    className="card-img-top embed-responsive-item"
                    src={`http://*********/${toy.images}`}
                  />
                </th>
                <th>$ {toy.price}</th>
                <th>
                  <button>Remove</button>
                </th>
              </tr>
           )}
        </thead>
      </table>
    </div>
  );
}

export default ClientCardBlock;

推荐阅读