反应状态不从临时变量设置对象
React state not setting Object from temporary variable
抱歉,我知道这是一个常见问题,但我找不到正确的答案。我正在使用一个功能组件,它从 API 中获取 JSON 个对象的列表。列表数据没有我需要的所有信息,因此我遍历提供的 ID 列表并获取每个 'show' JSON 确实有我需要的信息。然后我将它们放入状态数组中。这很混乱,但它运作良好。当我迭代和获取个人 'show' JSON 时,我想对某些值进行一些数学运算。我将该信息放入一个对象中,但是当我尝试将该对象设置为 state 它只是不起作用,即使我可以记录该对象并且它按预期显示。
const getStashList = async () => {
<Code to fetch list data>
}
useEffect(() => {
getStashList()
}, [])
const getFullStashData = (data) => {
const tempWeightObj = {}
let fullStashArray = []
try {
data.forEach(async (stashItem) => {
const indStashResponse = await fetch(`<the api address>`, {
method: 'GET',
headers: {
Authorization: "Bearer " + access_token
},
mode: 'cors'
})
const indStashData = await indStashResponse.json()
fullStashArray.push(indStashData.stash)
const amountStashed = indStashData.total_yards
let weightName = indStashData.weight_name
Object.defineProperty(tempWeightObj, weightName, {
value: amountStashed,
writable: true
})
console.log(tempWeightObj) //This logs the expected object
})
} catch (err) {
console.error(`Error in fetch: ${err.message}`)
}
setFullStash(fullStashArray) //This state is set as expected
setWeightYards(tempWeightObj) //The state is still empty
}
useEffect(() => {
getFullStashData(stashList)
}, [stashList])
getFullStashData
函数体是完全同步的。它声明 tempWeightObj
和 fullStashArray
,同步运行 forEach
,并将状态更新入队。 async
forEach
循环回调然后改变函数范围内关闭的引用。
你看到的是突变。
我建议重构,将 getFullStashData
函数声明为 async
,将 data
参数映射到 fetch
Promise 对象数组,等待数组响应映射到另一个 Promise 对象数组,这次返回 JSON 数据。您现在有 fullStashArray
数组来更新状态。迭代此 fullStashArray
数组以填充 tempWeightObj
对象的属性。全部完成后然后将状态更新加入队列。
const getFullStashData = async (data) => {
try {
const reqs = data.map((stashItem) =>
fetch(`<the api address>`, {
method: "GET",
headers: {
Authorization: "Bearer " + access_token
},
mode: "cors"
})
);
const responses = await Promise.all(reqs);
const fullStashArray = await Promise.all(responses.map((res) => res.json()));
const tempWeightObj = {};
fullStashArray.forEach(
({ total_yards: value, weight_name: weightName }) => {
Object.defineProperty(
tempWeightObj,
weightName,
{ value, writable: true }
);
}
);
setFullStash(fullStashArray);
setWeightYards(tempWeightObj);
} catch (err) {
console.error(`Error in fetch: ${err.message}`);
}
};
抱歉,我知道这是一个常见问题,但我找不到正确的答案。我正在使用一个功能组件,它从 API 中获取 JSON 个对象的列表。列表数据没有我需要的所有信息,因此我遍历提供的 ID 列表并获取每个 'show' JSON 确实有我需要的信息。然后我将它们放入状态数组中。这很混乱,但它运作良好。当我迭代和获取个人 'show' JSON 时,我想对某些值进行一些数学运算。我将该信息放入一个对象中,但是当我尝试将该对象设置为 state 它只是不起作用,即使我可以记录该对象并且它按预期显示。
const getStashList = async () => {
<Code to fetch list data>
}
useEffect(() => {
getStashList()
}, [])
const getFullStashData = (data) => {
const tempWeightObj = {}
let fullStashArray = []
try {
data.forEach(async (stashItem) => {
const indStashResponse = await fetch(`<the api address>`, {
method: 'GET',
headers: {
Authorization: "Bearer " + access_token
},
mode: 'cors'
})
const indStashData = await indStashResponse.json()
fullStashArray.push(indStashData.stash)
const amountStashed = indStashData.total_yards
let weightName = indStashData.weight_name
Object.defineProperty(tempWeightObj, weightName, {
value: amountStashed,
writable: true
})
console.log(tempWeightObj) //This logs the expected object
})
} catch (err) {
console.error(`Error in fetch: ${err.message}`)
}
setFullStash(fullStashArray) //This state is set as expected
setWeightYards(tempWeightObj) //The state is still empty
}
useEffect(() => {
getFullStashData(stashList)
}, [stashList])
getFullStashData
函数体是完全同步的。它声明 tempWeightObj
和 fullStashArray
,同步运行 forEach
,并将状态更新入队。 async
forEach
循环回调然后改变函数范围内关闭的引用。
你看到的是突变。
我建议重构,将 getFullStashData
函数声明为 async
,将 data
参数映射到 fetch
Promise 对象数组,等待数组响应映射到另一个 Promise 对象数组,这次返回 JSON 数据。您现在有 fullStashArray
数组来更新状态。迭代此 fullStashArray
数组以填充 tempWeightObj
对象的属性。全部完成后然后将状态更新加入队列。
const getFullStashData = async (data) => {
try {
const reqs = data.map((stashItem) =>
fetch(`<the api address>`, {
method: "GET",
headers: {
Authorization: "Bearer " + access_token
},
mode: "cors"
})
);
const responses = await Promise.all(reqs);
const fullStashArray = await Promise.all(responses.map((res) => res.json()));
const tempWeightObj = {};
fullStashArray.forEach(
({ total_yards: value, weight_name: weightName }) => {
Object.defineProperty(
tempWeightObj,
weightName,
{ value, writable: true }
);
}
);
setFullStash(fullStashArray);
setWeightYards(tempWeightObj);
} catch (err) {
console.error(`Error in fetch: ${err.message}`);
}
};