状态未在承诺的获取中更新(反应)

State not updating within a promised fetch (react)

我有一个表格,我用它向 api 发送数据。该数据用于创建后端管理员帐户并创建 post 条目。我需要 post 按 特定顺序 的数据,以从管理员帐户获取一些动态字段到 post。例如:

  1. 创建管理员帐户以创建一个 id 字段
  2. 使用 id 字段并应用于 post 在管理员帐户和 post
  3. 之间创建一个唯一的 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,
               [...]
            }
        })
    })
})