状态未在承诺的获取中更新(反应)
State not updating within a promised fetch (react)
我有一个表格,我用它向 api 发送数据。该数据用于创建后端管理员帐户并创建 post 条目。我需要 post 按 特定顺序 的数据,以从管理员帐户获取一些动态字段到 post。例如:
- 创建管理员帐户以创建一个 id 字段
- 使用 id 字段并应用于 post 在管理员帐户和 post
之间创建一个唯一的 link
除了我在获取新创建的帐户后尝试执行的 一次状态更新 之外,一切正常:
// dont know what the ID will be as its dynamic
const [theID, setTheID] = useState('');
//Send the data to firstly create the admin account (works fine)
fetch('example.com/api/cockpit/saveUser', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY
},
body: JSON.stringify({
user: {
user: firstname.toLowerCase()+surname.toLowerCase(),
name: firstname,
email: email,
password: password,
group: 'consumers',
}
})
})
.then(user => user.json())
// make next fetch a chain of the promise
// fetch all accounts but filter by email so will only return the right one
.then(()=>{
return fetch(`example.com/api/cockpit/listUsers&filter[email]=${email}`,{
method: 'post',
headers: {
'Content-Type': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY
}
})
})
.then((res) => {
return res.json();
})
.then((res)=>{
// the console log works fine
console.log(res[0]._id);
// the state returns undefined
setTheID(res[0]._id);
})
.catch((err)=>{
console.error(err);
})
//Then last fetch to make the post entry works fine ...
.then(()=>{
return fetch('example.com/api/collections/save/consumers', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY,
},
body: JSON.stringify({
data: {
firstname: firstname,
surname: surname,
password: password,
email: email,
project_name: projectName,
project_template: tmp,
// expected to get the dynamic ID front the state
ass_consumer: theID,
slug: projectName.toLowerCase().replace(' ','') + '-rr',
username: firstname.toLowerCase()+surname.toLowerCase()
}
})
})
})
.then(user => user.json())
.then((user)=>{
setnewPage(user._id);
})
我已经检查了控制台,它在获取后显示正常。我的所有其他状态更改都绑定到表单输入,但我以前从未遇到过在提取中更新状态的问题。
我也尝试创建一个函数,将电子邮件作为参数,然后 returns 状态发生变化,但也没有成功。
感谢任何帮助!
(使用驾驶舱作为我的api)
编辑
这是控制台日志returns:
(我只需要_id)
{
user: "johndoe",
name: "john",
email: "john.doe@example.com",
active: true,
group: "consumers",
_created: 1627039008,
_id: "60faa5203365618a38000035",
_modified: 1627039008,
}
您很可能在同一操作中读取状态(“太快”),因此状态更改不会反映出来,因为更新 React 状态的过程是异步的。
您有 2 个选项来始终获取最新的状态值:
要么使用对状态的引用(查看这个package)
或者使用“丑陋”的变通方法从 setState 中获取值,如下所示:
const [id, setId] = useState("")
setId("test")
console.log(id) // ""
// do this to get the up to date value, as the value
// in setState is always the most up to date one
let idVal
setId(current => {
idVal = current
return current
})
console.log(idVal) // "test"
所以在你的具体例子中,试试这个:
//Then last fetch to make the post entry works fine ...
.then(()=>{
let customerID
setTheID(current => {
customerID = current
return current
})
return fetch('example.com/api/collections/save/consumers', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY,
},
body: JSON.stringify({
data: {
[...]
// use the customerID variable, not the state variable
ass_consumer: customerID,
[...]
}
})
})
})
我有一个表格,我用它向 api 发送数据。该数据用于创建后端管理员帐户并创建 post 条目。我需要 post 按 特定顺序 的数据,以从管理员帐户获取一些动态字段到 post。例如:
- 创建管理员帐户以创建一个 id 字段
- 使用 id 字段并应用于 post 在管理员帐户和 post 之间创建一个唯一的 link
除了我在获取新创建的帐户后尝试执行的 一次状态更新 之外,一切正常:
// dont know what the ID will be as its dynamic
const [theID, setTheID] = useState('');
//Send the data to firstly create the admin account (works fine)
fetch('example.com/api/cockpit/saveUser', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY
},
body: JSON.stringify({
user: {
user: firstname.toLowerCase()+surname.toLowerCase(),
name: firstname,
email: email,
password: password,
group: 'consumers',
}
})
})
.then(user => user.json())
// make next fetch a chain of the promise
// fetch all accounts but filter by email so will only return the right one
.then(()=>{
return fetch(`example.com/api/cockpit/listUsers&filter[email]=${email}`,{
method: 'post',
headers: {
'Content-Type': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY
}
})
})
.then((res) => {
return res.json();
})
.then((res)=>{
// the console log works fine
console.log(res[0]._id);
// the state returns undefined
setTheID(res[0]._id);
})
.catch((err)=>{
console.error(err);
})
//Then last fetch to make the post entry works fine ...
.then(()=>{
return fetch('example.com/api/collections/save/consumers', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY,
},
body: JSON.stringify({
data: {
firstname: firstname,
surname: surname,
password: password,
email: email,
project_name: projectName,
project_template: tmp,
// expected to get the dynamic ID front the state
ass_consumer: theID,
slug: projectName.toLowerCase().replace(' ','') + '-rr',
username: firstname.toLowerCase()+surname.toLowerCase()
}
})
})
})
.then(user => user.json())
.then((user)=>{
setnewPage(user._id);
})
我已经检查了控制台,它在获取后显示正常。我的所有其他状态更改都绑定到表单输入,但我以前从未遇到过在提取中更新状态的问题。
我也尝试创建一个函数,将电子邮件作为参数,然后 returns 状态发生变化,但也没有成功。
感谢任何帮助!
(使用驾驶舱作为我的api)
编辑
这是控制台日志returns: (我只需要_id)
{
user: "johndoe",
name: "john",
email: "john.doe@example.com",
active: true,
group: "consumers",
_created: 1627039008,
_id: "60faa5203365618a38000035",
_modified: 1627039008,
}
您很可能在同一操作中读取状态(“太快”),因此状态更改不会反映出来,因为更新 React 状态的过程是异步的。
您有 2 个选项来始终获取最新的状态值:
要么使用对状态的引用(查看这个package)
或者使用“丑陋”的变通方法从 setState 中获取值,如下所示:
const [id, setId] = useState("") setId("test") console.log(id) // "" // do this to get the up to date value, as the value // in setState is always the most up to date one let idVal setId(current => { idVal = current return current }) console.log(idVal) // "test"
所以在你的具体例子中,试试这个:
//Then last fetch to make the post entry works fine ...
.then(()=>{
let customerID
setTheID(current => {
customerID = current
return current
})
return fetch('example.com/api/collections/save/consumers', {
method: 'post',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Cockpit-Token': process.env.REACT_APP_API_KEY,
},
body: JSON.stringify({
data: {
[...]
// use the customerID variable, not the state variable
ass_consumer: customerID,
[...]
}
})
})
})