想在 for 循环中设置状态对象:React+Typescript

Want to set a state object within a for loop: React+Typescript

我有一个状态对象,它基本上是一个对象数组。我正在执行一个 fetch 调用,它返回的对象数组应该设置为状态对象。但我不能这样做。 还有其他选择吗? 我哪里错了?

不胜感激

 this.state = {
      accounts: [{firstname:"",lastname:"",age:"",id:""}],
 };

 async componentDidMount(){

   let useraccounts =  await this.fetchAccounts();
   if(useraccounts.length > 0)
     { 
       for(let i=0;i<useraccounts.length;i++)
        {
            account = {firstname:useraccounts[i].firstname,lastname:useraccounts[i].lastname,age:useraccounts[i].age,id:useraccounts[i].id}; 
            this.setState((prevState) => ({  accounts: [ ...prevState.accounts, account ]}));            
        }                   
     }  
 }

 fetchAccounts = async() => {

    //fetch API call which will return all users accounts

 }

您无需为每个帐户单独调用 setState,只需对所有帐户调用一次即可:

async componentDidMount(){
  try {
    let useraccounts =  await this.fetchAccounts();
    let newAccounts = useraccounts.map(({firstname, lastname, age, id}) => ({firstname, lastname, age, id}));
    this.setState(({accounts}) => ({accounts: [...accounts, ...newAccounts]}));
  } catch (e) {
    // Do something with the error
  }
}

获取帐户,创建一个仅包含相关属性的新数组(您在 for 循环中所做的),然后调用 setState 添加新帐户。

请注意,我在 map 回调和 setState 回调的参数列表中进行解构,以仅挑选出它们接收到的我想要的对象部分。例如,这个:

let newAccounts = useraccounts.map(({firstname, lastname, age, id}) => ({firstname, lastname, age, id}));

与此相同:

let newAccounts = useraccounts.map(account => {
  return {
    firstname: account.firstname,
    lastname: account.lastname,
    age: account.age,
    id: account.id
  };
});

只是简洁了一点。

当然,如果你真的不需要复制对象,你可以直接使用从fetchAccounts获得的帐户:

async componentDidMount(){
  try {
    let useraccounts =  await this.fetchAccounts();
    this.setState(({accounts}) => ({accounts: [...accounts, ...useraccounts]}));
  } catch (e) {
    // Do something with the error
  }
}

关于您的原始代码的一些注释:

  • 您使用 async 函数违反了 promise 的规则之一,其中没有任何东西会处理 promise 它 returns: 您需要处理发生的任何错误,而不是无视他们。这就是为什么我添加了 try/catch.
  • 如果您正在执行 for(let i=0;i<useraccounts.length;i++),则无需先执行 if(useraccounts.length > 0)。如果没有帐户,您的循环体将不会 运行。