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