简体   繁体   中英

UseState not triggering re-render

I have a state for my orders list. On the first update everything is working fine but when an update is made on the order in the database, my order list is updated but not triggering a re-render even using <...>

 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]);

You are mutating the state.

  1. let oldOrders = orders; does not create a copy of array. It copies reference.
  2. setOrders(...oldOrders); makes no sense. You are spreading array as arguments but setOrders accepts 1 argument.
  3. If your next state depends on the previous state you should use callback form of setState
  4. You need to have oldOrders.unshift(...addedOrders); if you want to add multiple items not just a single array.

Your code should look somewhat like this assuming the rest of your logic is correct.

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]);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM