簡體   English   中英

我如何讓 usestate 在更新其值之前等待響應

[英]how do i make usestate wait for a response before updating its value

我正在建立一個電子商務商店,我正在使用 firebase(firestore 和存儲)。 我遇到的問題是,當我嘗試制作新產品時,我在useState state 中收集表單數據,並將thumbnail url 屬性留空。

當我點擊提交時,我將照片發布到 firebase 存儲並等待具有下載鏈接的響應,然后將鏈接推送到新產品使用 state,然后我將整個新產品使用 state 推送到數據庫中。 但是發生的事情是縮略圖 url 總是空的,當我將產品推送到數據庫時它是空的。

這是代碼

const [image, setImage] = React.useState(null); /*stores the image with all of its data */
const [newProduct, setNewProduct] = React.useState({
  title: "",
  brand: "",
  category: "",
  description: "",
  Offer: false,
  discountPercentage: 0,
  HotProduct: false,
  price: 0,
  stock: 0,
  rating: 0,
  thumbnail: "",
});

const add /* happens when i click submit*/ = (e) => {
  e.preventDefault();
  const imageRef = ref(storage, `images/${newProduct.id}`);
  uploadBytes(imageRef, image).then(async (snapshot) => {
    console.log("uploaded");
    await getDownloadURL(snapshot.ref).then((url) => {
      const path = url;
      setNewProduct((prev) => {
        return {
          ...prev,
          [newProduct.thumbnail]: path,
        };
      });
    });
      
    setDoc(doc(db, "products", newProduct.id.toString()), newProduct);
  });
};

const handleInput /*happens when i change the form input*/ = (event) => {
  const { name, value } = event.target;
  if (event.target.type === "file") {
    setImage(event.target.files[0]);
  } else {
    setNewProduct((prev) => {
      return {
        ...prev,
        id: Data.length,
        [name]: value,
      };
    });
  }
};

上面的代碼可能有點亂,因為我嘗試了很多東西。 我試圖使整個上傳圖像並獲取 url 然后將 state 上傳到數據庫,這有效,但useState掛鈎不會等待代碼獲取下載 url。

它似乎只有在我連續兩次將新產品 object 推送到數據庫中(運行 function 兩次)時才起作用。

如果我對您的帖子的理解正確,您想要調用add和獲取縮略圖資產以保存到newProduct.thumbnail屬性中。 您使用功能性 state 更新是在正確的軌道上,但代碼正在嘗試使用當前的newProduct.thumbnail作為newProduct state object 中的動態屬性鍵。您真的只想直接設置thumbnail屬性。 這部分沒有任何動態。

React state 更新函數是同步函數,您將無法在add function 回調 scope 中使用填充的thumbnail屬性訪問更新的newProduct setDoc調用應移動到具有某些依賴項的useEffect掛鈎,以確保newProduct具有id屬性thumbnail屬性。

const [newProduct, setNewProduct] = React.useState({
  id: 0,
  title: "",
  brand: "",
  category: "",
  description: "",
  Offer: false,
  discountPercentage: 0,
  HotProduct: false,
  price: 0,
  stock: 0,
  rating: 0,
  thumbnail: "",
});

useEffect(() => {
  if (newProduct.id && newProduct.thumbnail) {
    setDoc(doc(db, "products", newProduct.id.toString()), newProduct);
  }
}, [newProduct]);

const add = (e) => {
  e.preventDefault();

  const imageRef = ref(storage, `images/${newProduct.id}`);

  uploadBytes(imageRef, image)
    .then((snapshot) => getDownloadURL(snapshot.ref))
    .then((path) => {
      setNewProduct((thumbnail) => ({
        ...prev,
        thumbnail,
      }));
    });
  });
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM