React Hook UseEffect 结合 Firebase 创建无限循环

React Hook UseEffect in combination with Firebase creating infinite loop

我正在开发一个使用 Firebase 和 React 挂钩的项目。在加载 Web 应用程序之前,我想通过 运行 如下所示的查询从 Firebase 获取所有数据。

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 查询与 React Hooks 一起使用,比如 useEffect?现在,无论列表是否更改,useEffect 始终为 运行.

更新:

几件事:

1) 您的 useEffect 订阅了在此 useEffect 中设置的 lists,因此它触发了 re-run。

2) 您正在尝试更新项目,然后 re-fetch 所有数据包括更新的项目。你不需要这样做。从 Firebase 获得 "initial state" 后,所有修改都可能发生在状态内的列表中。是的,你会打电话来做 add/update/delete,但你不需要每次都打电话来获得一个全新的列表,因为你知道你改变了什么信息并且可以简单地更新你的状态列表来反映这一点同时还调用以实际更新基础数据,以便当您离开 Firebase 时,您的列表会反映出处于状态的列表。

太棒了!

从最后的 [] 中删除 lists 以便您的代码仅在安装时运行,如下所示:

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 []

然后,假设在 add 方法中,它看起来像下面这样:

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)
}

等等 update/delete 方法等等。您将只使用该状态值,而无需调用 Firebase 获取更新列表,因为您已经有了它。