我有一个React App,我有一个App容器,我想在其中调用fetch来获取一些数据以传递到需要该信息的组件。
我已经在onload函数(我的提取位于其中)的外部声明了变量,并在提取中为其分配了不同的值。它们的变量将在获取时更改,但在获取之外它们将保持不变。
为什么他们不会保持不变,有没有办法解决这个问题?
我尝试更改了用var而不是let声明的变量,并且尝试将函数放入const中。
我也尝试过将获取操作放到其他组件中(如下面的表格所示),但是随后我必须声明两个状态并在获取操作中调用获取操作,因为我已经在此处调用了另一个获取操作,并且变得麻烦...
let latestRelease = 0;
let draftRelease = 0;
let doClone = false;
function onload() {
fetch(url, {
method: 'GET'
})
.then(function(response) {
return response.json();
})
.then(function(result) {
for(var i = 0; i < result.length; i++)
{
if(result[i].id > latestRelease && result[i].status === "released") {
latestRelease = result[i].id;
}
if(result[i].id > draftRelease && result[i].status === "draft") {
draftRelease = result[i].id;
}
}
if(latestRelease > draftRelease) {
doClone = true;
}
})
.catch((error) => {
console.log(error);
});
}
const App: React.FC = () => {
onload()
return (
<React.Fragment>
<CssBaseline />
<Container fixed>
<PersistentDrawerLeft/>
{console.log(latestRelease)} //displays 0
<Title/>
<Table />
</Container>
</React.Fragment>
);
}
export default App;
我希望LatestRelease和draftRelease不会保持为0,而是大于0,但输出仅为0。返回正确的值后,我希望将它们作为道具传递给组件。
非常感谢!
答案 0 :(得分:1)
部分问题是您似乎无法正确地区分同步代码和异步代码。 fetch
是异步的,这意味着该代码不能保证在文件中的其他任何文件之前运行。 ({fetch
使用JS promises管理异步数据,因此有助于掌握using promises。)
在典型的React案例中,您想做一些不同的事情。首先,您要使用组件状态来保留数据,而不仅仅是随机变量(这使React可以在这些值更改时重新呈现)。其次,当异步获取数据时,需要弄清楚应用程序在获取完成之前应该做什么。
这是一个非常基本的示例,说明了它如何工作:
import React, { useState, useEffect } from 'react'
const App = ({ url }) => {
// We'll use this variable to store an object with the details
const [releaseDetails, setReleaseDetails] = useState(null)
// When the component is loaded, we'll fetch the url (coming from the component props) and then
// run your logic.
useEffect(() => {
let latestRelease = 0;
let draftRelease = 0;
let doClone = false;
fetch(url)
.then((response) => response.json())
.then((result) => {
for(var i = 0; i < result.length; i++) {
if(result[i].id > latestRelease && result[i].status === "released") {
latestRelease = result[i].id;
}
if(result[i].id > draftRelease && result[i].status === "draft") {
draftRelease = result[i].id;
}
}
if(latestRelease > draftRelease) {
doClone = true;
}
// To make these details available to the component, we'll bundle them into an object
// and update the component's state:
setReleaseDetails({
latestRelease,
draftRelease,
doClone
})
})
.catch((error) => {
// You'd ideally want some proper error handling here
console.log(error)
});
}, []) // pass an empty array so this is only run when the component is first rendered
// Because we're getting the data asynchronously, we need to display something while we wait
if(releaseDetails === null) {
return "loading..."
}
// Once the data is available, you can then use the details when rendering. You could instead
// render a child component and pass the values as props to it.
return (
`LatestRelease: ${releaseDetails.latestRelease}`
)
}
一般来说,您可能需要确保有一些React和一般的JS概念,以确保您可以使用,尤其是在状态和异步数据获取方面。不确定目前为止您有多少经验,但是您可能想看一下一些入门教程(可能像this official one),以了解您可以遵循的内容以及是否有什么可以跳过的内容。您需要熟悉一些东西。
答案 1 :(得分:0)
请尝试使用状态变量,因为如果状态变量更改,则渲染将再次调用,此处您使用的普通变量可能是其更改但不是渲染。
谢谢。
答案 2 :(得分:0)
变量应处于可重新渲染的状态