Reactjs 在接收来自useEffect的数据之前呈现页面

Reactjs 在接收来自useEffect的数据之前呈现页面,reactjs,Reactjs,我是React的新手,我正在用React、typescript和自制的API构建一个webshop 我正在尝试使购物车组件正常工作。它从API中获取产品的ID,并基于这些ID获取具有这些ID的产品,然后将产品放入数组dinosArray中 现在,我尝试在表中为dinosArray中的每个产品呈现一个新行。我的问题是,行的映射和渲染发生在填充dinosArray之前,这导致没有添加行,因为在映射dinosArray时,dinosArray是空的 如何实现基于dinosArray中的每个条目在表中呈

我是React的新手,我正在用React、typescript和自制的API构建一个webshop

我正在尝试使购物车组件正常工作。它从API中获取产品的ID,并基于这些ID获取具有这些ID的产品,然后将产品放入数组dinosArray中

现在,我尝试在表中为dinosArray中的每个产品呈现一个新行。我的问题是,行的映射和渲染发生在填充dinosArray之前,这导致没有添加行,因为在映射dinosArray时,dinosArray是空的

如何实现基于dinosArray中的每个条目在表中呈现新行的目标

以下是组件的代码:

import React, { useEffect, useState } from "react";
import { Table } from "react-bootstrap";
import "../css/stylesheet.css";

export default function Cart() {
  var dinosArray: any = []



  const getProducts = async () => {
    let apiUrl = "http://localhost:3005/velocishop/customers/" + localStorage.uuid + "/baskets/" + localStorage.uuid + "/products"
    let response = await fetch(apiUrl)
    let products = await response.json()
    console.log("this is products")
    console.log(products)
    products.map((product: any) => {
      fetchDino(product)
    })
    console.log("this is dinosArray")
    console.log(dinosArray)
  }


  function fetchDino(product: number) {
    console.log("in fetchDino")
    var url: string = "http://localhost:3005/velocishop/products/" + product
    fetch(url, {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
    }).then(response => {
      if (response.ok)
        return Promise.resolve({ status: response.statusText }) && response.json()
      else
        return response.json()
    }
    )
      .then(response => JSON.stringify(response))
      .then(response => JSON.parse(response))
      .then(data => dinosArray.push(data))
      .catch(err => console.log(err))

    //renderProducts()
  }

  useEffect(() => {
    getProducts()
  }, [])

  function renderProducts() {

    console.log("in renderProducts(), this is dinosArray:")
    console.log(dinosArray)

    return (
      <div>
        {dinosArray.map((dino: any) => (
          <tr>
            <td>{dino.productName}</td>
          </tr>
        ))}
      </div>
    )

  }


  return (
    <div className="register-wrapper">
      <Table responsive="sm">
        <thead>
          <tr>
            <th><h1 className="italic-header">Products in cart</h1></th>
          </tr>
        </thead>
        <tbody>
          {renderProducts()}
        </tbody>
      </Table>
    </div>
  )
}
import React,{useffect,useState}来自“React”;
从“react bootstrap”导入{Table};
导入“./css/stylesheet.css”;
导出默认函数Cart(){
var dinosArray:any=[]
const getProducts=async()=>{
让apiUrl=”http://localhost:3005/velocishop/customers/“+localStorage.uuid+”/baskets/“+localStorage.uuid+”/products”
let response=等待获取(APIRL)
let products=wait response.json()
console.log(“这是产品”)
console.log(产品)
products.map((产品:任意)=>{
费奇迪诺(产品)
})
log(“这是迪诺萨雷”)
控制台日志(dinosArray)
}
函数fetchDino(产品编号){
log(“在fetchDino中”)
变量url:字符串=”http://localhost:3005/velocishop/products/“+产品
获取(url{
方法:“获取”,
标题:{
接受:“应用程序/json”,
“内容类型”:“应用程序/json”,
},
})。然后(响应=>{
if(response.ok)
返回Promise.resolve({status:response.statusText})和&response.json()
其他的
返回response.json()
}
)
.then(response=>JSON.stringify(response))
.then(response=>JSON.parse(response))
.then(数据=>dinosArray.push(数据))
.catch(err=>console.log(err))
//renderProducts()
}
useffect(()=>{
getProducts()
}, [])
函数renderProducts(){
log(“在renderProducts()中,这是dinosArray:)
控制台日志(dinosArray)
返回(
{恐龙阵地图((恐龙:任何)=>(
{dino.productName}
))}
)
}
返回(
购物车中的产品
{renderProducts()}
)
}
您需要使用状态

状态是组件所具有的值,当设置新状态时,该值会导致组件重新渲染

因此,在这种情况下,请更改以下内容:

var dinosArray: any = []
.then(data => dinosArray.push(data))
致:

现在,只要有新数据,就调用
setDinosArray(myNewDinosArray)


接下来,更改此选项:

var dinosArray: any = []
.then(data => dinosArray.push(data))
致:

由于有许多异步函数正在更新此状态,因此可以将函数传递给
setDinosArray
,该函数始终将当前状态作为第一个参数。这意味着您每次添加内容时,都会获得最新的
dinosArray


州是React的一个基本支柱,您应该在官方文档中了解更多:
我认为你应该使用useState钩子。您可以定义
const[dinosArray,setDinosArray]=useState([]),而不是
var-dinosArray:any=[]
在你做的地方推送(数据)你可以做一些类似于setDinosArray([…dinosArray,data])你已经导入了useState钩子,但是你没有使用它。将其添加到组件中,并在以下行中设置为response.ok==true

if (response.ok)
        return Promise.resolve({ status: response.statusText }) && response.json()
      else
        return response.json()

您可以使用该钩子返回的值来决定渲染什么

谢谢您的回答!我试着实现你的建议。但是,当将.then(data=>dinosArray.push(data))替换为.then(data=>setDinosArray(dinosArray=>[…dinosArray,data])时,它不会编译并显示错误“类型的参数”(dinosArray:never[])=>any不能分配给类型为“SetStateAction”的参数。type(dinosArray:never[])=>any不能分配给类型为(prevState:never[])=>never[]”。类型“any[]”不可分配给类型“never[]”。类型“any”不可分配给类型“never”。“您知道如何解决此问题吗?我通过将此类型添加到useState:const[dinosArray,setDinosArray]=useState([])来修复此错误任何
any
都应该是单个恐龙对象的形状。例如
useState([])
使用强类型非常重要,这样Typescript就可以做得最好。