【问题标题】:UseState not triggering re-renderUseState 不会触发重新渲染
【发布时间】:2021-03-03 10:46:41
【问题描述】:

我的订单列表有一个状态。在第一次更新时一切正常,但是当对数据库中的订单进行更新时,我的订单列表已更新,但即使使用 <...>

也不会触发重新渲染

const [orders, setOrders] = useState([]);

  useEffect(() => {
    const unsubscribe = firebase.firestore()
      .collection("Orders")
      .orderBy("date", "desc")
      .limit(parseInt(limit, 10))
      .onSnapshot((snapshot) => {
        let oldOrders = orders;
        let addedOrders = []

        snapshot.docChanges().forEach((change) => {
          if (change.type === "added") {
            addedOrders.push({ ...change.doc.data(), id: change.doc.id })
          }
          if (change.type === "modified") {
            oldOrders[oldOrders.findIndex(x => x.id === change.doc.id)] = { ...change.doc.data(), id: change.doc.id }
          }
          if (change.type === "removed") {
            oldOrders.splice(oldOrders.findIndex(x => x.id === change.doc.id))
          }
        });
        if (addedOrders.length > 0) {
          oldOrders.unshift(addedOrders)
        }
        setOrders(...oldOrders);
      });
    return () => {
      unsubscribe()
    }
  }, [limit]);

【问题讨论】:

    标签: javascript reactjs react-hooks state


    【解决方案1】:

    你正在改变状态。

    1. let oldOrders = orders; 不会创建数组的副本。它复制参考。
    2. setOrders(...oldOrders); 毫无意义。您将数组作为参数传播,但 setOrders 接受 1 个参数。
    3. 如果你的下一个状态依赖于前一个状态,你应该使用setState的回调形式
    4. 如果要添加多个项目而不仅仅是单个数组,则需要 oldOrders.unshift(...addedOrders);

    假设你的其余逻辑是正确的,你的代码应该看起来像这样。

    useEffect(() => {
      const unsubscribe = firebase
        .firestore()
        .collection("Orders")
        .orderBy("date", "desc")
        .limit(parseInt(limit, 10))
        .onSnapshot((snapshot) => {
          // use callback form to avoid relying on stale state
          setOrders((orders) => {
            let oldOrders = [...orders]; // create new array
            let addedOrders = [];
    
            snapshot.docChanges().forEach((change) => {
              if (change.type === "added") {
                addedOrders.push({ ...change.doc.data(), id: change.doc.id });
              }
              if (change.type === "modified") {
                oldOrders[oldOrders.findIndex((x) => x.id === change.doc.id)] = {
                  ...change.doc.data(),
                  id: change.doc.id,
                };
              }
              if (change.type === "removed") {
                oldOrders.splice(
                  oldOrders.findIndex((x) => x.id === change.doc.id)
                );
              }
            });
            if (addedOrders.length > 0) {
              oldOrders.unshift(...addedOrders);
            }
    
            return oldOrders;
          });
        });
      return () => {
        unsubscribe();
      };
    }, [limit]);
    

    【讨论】:

    • 谢谢它的工作,但我必须在每个 oldOrders 之后添加 [0] 否则我在数组中有数组,你知道为什么吗?
    • @Joris 如果你想添加多个项目,它必须是oldOrders.unshift(...addedOrders);
    猜你喜欢
    • 2020-06-02
    • 2022-01-25
    • 1970-01-01
    • 2020-10-29
    • 2020-01-26
    • 1970-01-01
    • 2021-08-04
    • 2020-01-13
    相关资源
    最近更新 更多