数据是从后台抓取的,但是界面上没有显示

The data is fetched from the backend, but it is not displayed on the interface

我有一个ECommerce项目,这个项目包含展示商品、创建商品、删除商品、展示具体商品信息等操作。

我的问题只在于显示数据。

其中通过App文件,从后台抓取数据传递给“Products”组件,然后显示在界面上。

问题是从后台取数据,后台传来的数据出现在浏览器中,请求成功,但是问题是数据没有显示在界面上,界面是完全空了。

我该如何解决这个问题?

App.js:

import * as React from "react";
import Navbar from "./Navbar";
import Products from "./Products";
import { getAllProducts } from "../services/ECommerceServices";

const App = () => {
  console.log("Hi in App file");
  //   const [products, setProducts] = React.useState([]);

  const getAllProductsFun = () => {
    console.log("Hi I am in App file get all products");
    getAllProducts().then((products) => {
      //   console.log(products);
      //   setProducts(products);
      console.log("pppppppppppp: ", products);
      return products;
    });
  };

  return (
    <>
      <Navbar />
      <Products getAllProductsFun={getAllProductsFun} />
    </>
  );
};

export default App;

products.js:

import * as React from "react";
import { styled } from "@mui/material/styles";
import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper";
import Grid from "@mui/material/Grid";
import { makeStyles } from "@mui/styles";
import { Typography } from "@mui/material";
import Head from "next/head";
import useMediaQuery from "@mui/material/useMediaQuery";
import { useTheme } from "@mui/material/styles";
import Dialog from "./Dialog";
import Product from "./Product";
import { getAllProducts } from "../services/ECommerceServices";

const Item = styled(Paper)(({ theme }) => ({
  backgroundColor: theme.palette.mode === "dark" ? "#1A2027" : "#fff",
  ...theme.typography.body2,
  padding: theme.spacing(1),
  textAlign: "center",
  color: theme.palette.text.secondary,
}));

const useStyles = makeStyles({
  main: {
    padding: "4rem ",
  },
  typo: {
    color: "#ffc400 !impoertant",
  },
  // button: {
  //   textTransform: "none !important",
  //   backgroundColor: "#ffc400 !important",
  //   color: "white  !important",
  //   padding: 14,
  // },
});

function Products({ getAllProductsFun }) {
  console.log("check: ", getAllProductsFun);
  const theme = useTheme();
  const breakpoint = useMediaQuery(theme.breakpoints.down("sm"));

  return (
    <>
      <Head>
        <title>Solek</title>
      </Head>
      <Grid
        container
        direction={breakpoint ? "column" : "row"}
        style={{ margin: "4rem" }}
      >
        <Grid item xs={12} sm={9} md={9}>
          <Typography
            variant="h4"
            gutterBottom
            component="div"
            // className={classes.typo}
            style={{ fontWeight: 600 }}
          >
            Our Products
          </Typography>
        </Grid>
        <Grid
          item
          xs={12}
          md={3}
          sm={3}
          style={{
            direction: "row",
            justifyContent: "flex-end",
            alignItems: "center",
          }}
        >
          <Dialog />
        </Grid>
      </Grid>
      <Box sx={{ flexGrow: 1, margin: 8 }}>
        <Grid container spacing={3}>
          {getAllProductsFun()?.map((product, index) => (
            <Grid item xs={12} sm={6} md={3} key={index}>
              <Item>
                {" "}
                <Product key={product.id} product={product} />;
              </Item>
            </Grid>
          ))}
        </Grid>
      </Box>
    </>
  );
}

export default Products;

EcommerceServices.js:

import axios from "axios";

// [id]

// get All Products
// export async function getAllProducts() {
//   const res = await axios.get("https://fakestoreapi.com/products");
//   const products = await res.data;
//   console.log("products: ", products);
//   return products;
// }

export async function getAllProducts() {
  const res = await axios
    .get("https://fakestoreapi.com/products")
    .then((res) => {
      const products = res.data;
      console.log("products: ", products);
      return products;
    });

  return res;
}

// get element by ID
export async function getSingleProductRequest(context) {
  const id = context.params.id;
  const req = await axios.get("https://fakestoreapi.com/products/" + id);
  const product = await req.json();
  console.log("product: ", product);
  return product;
}

// get product by ID
export async function getProductsOneByOne() {
  const req = await fetch("https://fakestoreapi.com/products");
  const products = await req.json();
  const paths = products.map((product) => {
    return {
      params: {
        id: product.id.toString(),
      },
    };
  });
  return {
    paths,
    fallback: false,
  };
}

// delete product
export const deleteProduct = async (id) => {
  await axios
    .delete(`https://fakestoreapi.com/products/${id}`)
    .then((res) => {
      res.json();
      console.log("data: ", res.json());
    })
    .then((json) => {
      console.log("json data: ", json);
    })
    .catch((err) => console.log("error: ", err));
};

问题是您的 getAllProductsFun api 调用是异步的。因此,您需要保存这些值然后显示它,而不是尝试在渲染时调用它。

在您的 App.js 中,您可以创建一个状态来存储获取的产品并在您的应用安装上调用该函数,如下所示:

const App = () => {
  const [products, setProducts] = React.useState([]) // defaults to empty array

  ...

  React.useEffect(() => {
    getAllProducts().then(response => setProducts(response))
  }, []) // empty deps array means it will only call once on mount

  return (
    <>
      <Navbar />
      <Products products={products} />
    </>
  );
}

现在您可以像这样在 Products 中呈现结果:

function Products({ products }) {
   ...

   return (
     ...
     {products.map(...)}
     ...
   )
}