繁体   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