消防站吓坏了

时间:2019-05-21 14:36:45

标签: javascript reactjs firebase google-cloud-firestore

我刚刚在另一个域(生产URL)下打开了我的项目,当我打开网络请求时,我看到了:

https://i.imgur.com/NxgTmIf.mp4

这花了整整八分钟或更长时间。我的CPU像地狱一样热,我做错了什么?

我的应用程序非常简单,我怀疑其根本原因是以下代码块:

  const [items, setItems] = useState([]);

  const publish = async () => {
    const batch = firestore.batch();

    items.forEach(({ id }, index) => {
      batch.update(firestore.collection('v1').doc(id), { '#': index });
    });

    await batch.commit();
  };

  const onCompletion = querySnapshot => {
    const arr = [];

    querySnapshot.forEach(document => {
      const { vid: { id: vid }, '#': index } = document.data();

      const { id } = document;

      arr.push({ id, vid, index });
    });

    setItems(arr);
  };

  useEffect(() => {
    const unsubscribe = firestore
      .collection('v1')
      .orderBy('#')
      .onSnapshot(onCompletion);

    return () => {
      unsubscribe();
    };
  }, []);

  useEffect(() => { publish(); }, [items]);

  const handleSortEnd = ({ oldIndex, newIndex }) => {
    if (oldIndex === newIndex) {
      return;
    }

    setItems(arrayMove(items, oldIndex, newIndex));
  };

基本上,这是从Firestore的收藏列表中的播放列表中加载视频列表,然后在用户添加新视频或再次上/下保存之后。

有任何线索吗?

编辑:疯狂之后,该应用程序几乎没有执行请求,并且按预期运行。

2 个答案:

答案 0 :(得分:2)

我认为要加载您的状态有很多次,原则上应该进行更新。为什么不在提交快照之前将其分类为所需的状态。给出一个条件,仅在“项目”具有期望值时进行排序。

另一种方法是从Firestore中获取“ setItems”,并在状态渲染过程中对数据进行排序,而不是在渲染之前点击状态。

此外,每次对数据进行排序时都会将一组新数据设置为状态。 React会将它们当作渲染前的新数据,这效率不高。

答案 1 :(得分:2)

如果我正确执行此操作,则您有一个useEffect()订阅了对“ v1” firestore集合的更改。首次加载组件时,并且在集合文档中进行后续更改时,会触发onSnapshot事件,调用onCompletiononCompletion然后将集合中的所有文档提取到一个新数组中,然后将其分配给您的items状态。您的其他useEffect()语句在items更改时触发,调用publish函数,该函数对同一“ v1”集合中的文档执行批处理更新,这将触发{{1 }}再次调用onSnapshot,该循环将不停地重复。

在组件加载后一次检索集合的文档 可能更有意义,然后使用结果初始化onCompletion状态,然后在{{1 }}已更新。您无需通过集合订阅再次检索文档,因为您已经将它们保存在items数组中。