提问者:小点点

来自状态的对象数组查询时返回长度0,但记录数组显示正确的长度[重复]


在函数内部,我首先创建一个当前状态的数组,在for循环中使用。但是当试图获取它的长度时,它返回0。从状态和新数组记录数组表明数组确实包含正确的对象,甚至将长度显示为适当的数量。

console.log(this.state.teams);
console.log(this.state.teams.length);
let sortedTeams = this.state.teams;
console.log(sortedTeams);
console.log(sortedTeams.length);

是什么导致长度返回为0,即使它显然不是??数组从fi恢复映射如下:

getTeamsAndSort() {
    let teams = [];
    docRef.collection('Teams').get()
    .then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
            let name = doc.data().name;
            let seeding = doc.data().seeding;
            let team = {name, seeding};
            teams.push(team);
        });
        teams.sort((a, b) => (a.seeding > b.seeding) ? 1 : -1);
    });
    this.setState({teams});
};

在我调用getTeamsandSort()后立即调用我需要team[]长度的函数,以防它是异步问题。


共2个答案

匿名用户

是什么导致长度返回为0,即使它显然不是??

这是因为当您记录它时,长度是0。但是,如果您将鼠标悬停在“i”图标上(在Chrome检查控制台中),您将看到一条消息,说明随着对象的更改,控制台中的对象将更新。

您可以通过以下方式防止误导性日志:

console.log(JSON.parse(JSON.stringify(sortedTeams)));

您问题的可能解决方案:

getTeamsAndSort = () => {
    let teams = [];
    docRef.collection('Teams').get()
    .then(querySnapshot => {
        querySnapshot.forEach(function(doc) {
            let name = doc.data().name;
            let seeding = doc.data().seeding;
            let team = {name, seeding};
            teams.push(team);
        });
        teams.sort((a, b) => (a.seeding > b.seeding) ? 1 : -1);
        return new Promise((resolve, reject) => {
            // resolve the promise after state is set
            this.setState({teams}, resolve);
        })
    });
};

然后,如果您需要在调用getTeamsAndSort后立即使用this. state.team,请等待Promise以确保在记录或访问其属性之前更新了状态。

async someFunc() {
    await getTeamsAndSort()
    console.log(JSON.parse(JSON.stringify(sortedTeams)));
}

匿名用户

docRef. Collection('Teams').get()是异步的,在查询完成之前立即返回。事实上,所有返回Promise的函数都将以相同的方式运行。您的代码必须仅在Promise在然后块中解析后使用查询的结果。

您的代码正在调用this. setState({team});在数据库结果完成之前使用一个空的团队数组。您应该只在回调中设置状态:

getTeamsAndSort() {
    let teams = [];
    docRef.collection('Teams').get()
    .then(querySnapshot => {
        querySnapshot.forEach(function(doc) {
            let name = doc.data().name;
            let seeding = doc.data().seeding;
            let team = {name, seeding};
            teams.push(team);
        });
        teams.sort((a, b) => (a.seeding > b.seeding) ? 1 : -1);
        // only set the state after the teams are available
        this.setState({teams});
    });
};

还要记住,在调用getTeamsAndSort后,您将无法立即访问团队的长度,因为整个事情现在是异步的。底线是您必须学习如何有效地处理Promise才能处理这样的数据库查询。