想在 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)
。如果没有帐户,您的循环体将不会 运行。
我有一个状态对象,它基本上是一个对象数组。我正在执行一个 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)
。如果没有帐户,您的循环体将不会 运行。