React - Firebase 两次写入数据,问题出在哪里?

React - Firebase writing data twice, where is the problem?

我的项目遇到了问题。我想从 firebase 写入数据,它可以工作,但元素成倍增加。

写入数据的代码如下:Here is a photo of elements displaying.

const db = getDatabase();
const starCountRef = ref(db, `/Animals`);
onValue(starCountRef, (snapshot) => {
    let data = snapshot.exportVal();

    Object.keys(data).forEach((id) => {
        animals.push(data[id])
    })    
});

其余代码:

return (
        <>
            <div className="adoption-cards container">
                <ul className="cards-list">
                    {
                        Object.keys(animals).map((id) => {
                            return (
                                <li key={animals[id].id} className="card-item">
                                    <div className="card">
                                        <div className="photo-container">
                                            <img src={animals[id].photo} alt="animal" className="animal-photo"/>
                                        </div>
                                        <div className="animal-info">
                                            <p>
                                                <span>Imię:</span>{animals[id].name}
                                            </p>
                                            <p>
                                                <span>Gatunek:</span>{animals[id].type}
                                            </p>
                                            <p>
                                                <span>Płeć:</span>{animals[id].sex}
                                            </p>
                                            <p>
                                                <span>Wiek:</span>{animals[id].age}
                                            </p>
                                        </div>
                                        <div className="animal-description">
                                            <p className="description-title">Opis:</p>
                                            <p className="animal-story">{animals[id].story}</p>
                                            <button className="adopt-btn">Adoptuj</button>
                                        </div>
                                    </div>
                                </li>
                            )
                        })
                    }
                </ul>
            </div>
        </>
    );
};

当数据库中的数据发生变化时,很可能会发生这种情况。

当您使用 onValue 时,您的回调将立即使用数据库中的当前值进行调用,然后在每次数据更改时再次调用并更新数据快照。由于您每次都向 animals 添加数据,因此第二次 re-adding 数据量很大。


如果只想获取一次数据,请使用get而不是onSnapshot:

const db = getDatabase();
const starCountRef = ref(db, `/Animals`);
get(starCountRef).then((snapshot) => {  // 
    ...   
});

如果您想监听更改,请在获得数据更新时清除 animals 数组:

const db = getDatabase();
const starCountRef = ref(db, `/Animals`);
onValue(starCountRef, (snapshot) => {
    animals = []; // 
    ...   
});

无关,这是从 Firebase 的快照中获取数据的更惯用的方法:

snapshot.forEach((child) => {
    animals.push(child.val())
})