Reactjs React Hook Useffect结合Firebase创建无限循环
我正在做一个使用Firebase和React挂钩的项目。在加载web应用程序之前,我希望通过运行如下所示的查询从Firebase获取所有数据Reactjs React Hook Useffect结合Firebase创建无限循环,reactjs,firebase,react-hooks,Reactjs,Firebase,React Hooks,我正在做一个使用Firebase和React挂钩的项目。在加载web应用程序之前,我希望通过运行如下所示的查询从Firebase获取所有数据 const [lists, setLists] = useState([]); useEffect(() => { const dataArray = []; /** handleWidgets */ listsRef .once('value', snap => { snap.forEach(function
const [lists, setLists] = useState([]);
useEffect(() => {
const dataArray = [];
/** handleWidgets */
listsRef
.once('value', snap => {
snap.forEach(function(result) {
firebase
.database()
.ref('lists')
.child(result.key)
.on('value', snap => {
if (snap.val()) dataArray.push(snap.val());
});
});
})
.then(function() {
setLists(dataArray);
});
}, [lists]);
出于某种原因,useEffect总是在运行,并造成了巨大的性能问题。有没有更好的方法将Firebase查询与诸如useEffect之类的React挂钩一起使用?现在,如果列表已更改或未更改,useEffect将始终运行。已更新:
有几件事:
1) 您的useffect
正在订阅此useffect
中设置的列表
,因此它将触发重新运行
2) 您正在尝试更新项目,然后重新获取包括更新项目在内的所有数据。你不需要这样做。一旦您从Firebase获得“初始状态”,所有修改都可能发生在状态中的列表上。是的,您将打电话进行添加/更新/删除,但您不需要每次都打电话获取全新的列表,因为您知道您更改了哪些信息,并且可以简单地更新状态列表以反映这一点,同时也可以打电话实际更新基础数据,以便当您离开Firebase时,您的列表会反映处于状态的列表
所以
从末尾的[]
中删除列表
,使您的代码只在装载时运行,如下所示:
const [lists, setLists] = useState([]);
useEffect(() => {
const dataArray = [];
/** handleWidgets */
listsRef
.once('value', snap => {
snap.forEach(function(result) {
firebase
.database()
.ref('lists')
.child(result.key)
.once('value', snap => {
if (snap.val()) dataArray.push(snap.val());
});
});
})
.then(function() {
setLists(dataArray);
});
}, []); // removed lists from subscription []
addItem = listItem => {
// make copy of array in state
const newLists = [...lists];
// add item to list
newLists.push(listItem);
// update list in DB with firebase
/* firebase call here with new list item */
// update state lists with new array that has new item
setLists(newLists)
}
然后,让我们假设在add方法中,它看起来如下所示:
const [lists, setLists] = useState([]);
useEffect(() => {
const dataArray = [];
/** handleWidgets */
listsRef
.once('value', snap => {
snap.forEach(function(result) {
firebase
.database()
.ref('lists')
.child(result.key)
.once('value', snap => {
if (snap.val()) dataArray.push(snap.val());
});
});
})
.then(function() {
setLists(dataArray);
});
}, []); // removed lists from subscription []
addItem = listItem => {
// make copy of array in state
const newLists = [...lists];
// add item to list
newLists.push(listItem);
// update list in DB with firebase
/* firebase call here with new list item */
// update state lists with new array that has new item
setLists(newLists)
}
等等,等等,从更新/删除方法开始。您只需使用该状态值,而无需调用Firebase以获取更新列表,因为您已经拥有该列表。更新:
有几件事:
1) 您的useffect
正在订阅此useffect
中设置的列表
,因此它将触发重新运行
2) 您正在尝试更新项目,然后重新获取包括更新项目在内的所有数据。你不需要这样做。一旦您从Firebase获得“初始状态”,所有修改都可能发生在状态中的列表上。是的,您将打电话进行添加/更新/删除,但您不需要每次都打电话获取全新的列表,因为您知道您更改了哪些信息,并且可以简单地更新状态列表以反映这一点,同时也可以打电话实际更新基础数据,以便当您离开Firebase时,您的列表会反映处于状态的列表
所以
从末尾的[]
中删除列表
,使您的代码只在装载时运行,如下所示:
const [lists, setLists] = useState([]);
useEffect(() => {
const dataArray = [];
/** handleWidgets */
listsRef
.once('value', snap => {
snap.forEach(function(result) {
firebase
.database()
.ref('lists')
.child(result.key)
.once('value', snap => {
if (snap.val()) dataArray.push(snap.val());
});
});
})
.then(function() {
setLists(dataArray);
});
}, []); // removed lists from subscription []
addItem = listItem => {
// make copy of array in state
const newLists = [...lists];
// add item to list
newLists.push(listItem);
// update list in DB with firebase
/* firebase call here with new list item */
// update state lists with new array that has new item
setLists(newLists)
}
然后,让我们假设在add方法中,它看起来如下所示:
const [lists, setLists] = useState([]);
useEffect(() => {
const dataArray = [];
/** handleWidgets */
listsRef
.once('value', snap => {
snap.forEach(function(result) {
firebase
.database()
.ref('lists')
.child(result.key)
.once('value', snap => {
if (snap.val()) dataArray.push(snap.val());
});
});
})
.then(function() {
setLists(dataArray);
});
}, []); // removed lists from subscription []
addItem = listItem => {
// make copy of array in state
const newLists = [...lists];
// add item to list
newLists.push(listItem);
// update list in DB with firebase
/* firebase call here with new list item */
// update state lists with new array that has new item
setLists(newLists)
}
等等,等等,从更新/删除方法开始。您将只使用该状态值,而不调用Firebase来获取更新列表,因为您已经拥有了它。问题是,当用户插入新列表项或更改标题时,我想更新DOM。然后我想重新运行查询并从Firebase获取新数据。当用户更新列表值或插入新项时,是否也调用Firebase来更新基础数据?是的,它将获得新数据,但需要重新渲染dom我已更新我的答案-如果这仍然无法回答/解决您的问题,请告诉我。问题是,当用户插入新列表项或更改标题时,我想更新dom。然后,我想重新运行查询并从Firebase获取新数据。当用户更新列表值或插入新项时,是否也调用Firebase来更新基础数据?是的,它将获取新数据,但需要重新渲染dom。我已更新了我的答案-如果仍然无法回答/解决您的问题,请告诉我