简体   繁体   English

React-native Cloudinary 图像上传问题 state

[英]React-native Cloudinary image upload problem with state

I am building an app with react-native and EXPO CLI, and I have a screen which I am fetching an image/several images from a user in the registration process.我正在使用 react-native 和 EXPO CLI 构建一个应用程序,并且我有一个屏幕,我在注册过程中从用户那里获取图像/多张图像。 I want to fetch the image from the user's gallery, then upload it to cloudinary and generate a url, and then push this url into the Database and render it on the screen after.我想从用户的图库中获取图像,然后将其上传到 cloudinary 并生成 url,然后将此 url 推送到数据库中,然后在屏幕上呈现。

The images are being uploaded to Cloudinary successfully, but it doesn't return the url in time, resolving in the 'imagesUrl' state to be empty when I push the data into the Database.图像已成功上传到 Cloudinary,但它没有及时返回 url,当我将数据推送到数据库时,在“imagesUrl”state 中解析为空。 So basically after a while in Cloudinary I see my images, but In the database under the "images" field, I get an empty array, which is being set to a state which is also empty at the time.因此,基本上在 Cloudinary 中过了一段时间后,我看到了我的图像,但是在“图像”字段下的数据库中,我得到了一个空数组,该数组被设置为 state,当时它也是空的。 The setState is not working properly. setState 工作不正常。

My code:我的代码:

Local states:地方州:

  const [images, setImages] = useState([]);

  const [imagesUrl, setImagesUrl] = useState([]);

Function responsible for picking an image from a user's gallery: Function 负责从用户的图库中挑选图像:

 const pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });

    if (!result.cancelled) {
      if (images.length < 6) setImages((prev) => [...prev, result]);
    }
  };

Function responsible for uploading to Cloudinary: Function 负责上传到Cloudinary:

 const handleUploads = async (files) => {
    const formData = new FormData();

    for (let i = 0; i <= files.length; i++) {
      let file = files[i];
      formData.append("file", file);
      formData.append("upload_preset", "wingman");
      formData.append("cloud_name", "drsgaixjb");

      const res = await fetch(`${CLOUDINARY_URL}/image/upload`, {
        method: "POST",
        body: formData,
      });

      const cloudinaryFiles = await res.json();
      setImagesUrl([...imagesUrl, cloudinaryFiles.url]);
    }
  };

Function responsible to convert the files that the user upload to the right type: Function 负责将用户上传的文件转换为正确的类型:

 const handleImagesType = (imgs) => {
    let newImages = [];
    imgs.forEach((img) => {
      newImages.push({
        uri: img.uri,
        type: `test/${img.uri.split(".")[1]}`,
        name: `test/${img.uri.split(".")[1]}`,
      });
    });
    return newImages;
  };

And the last function which is responsible of pushing the data into the database:最后一个负责将数据推入数据库的function:

  const pushDataHandler = async (data) => {
    if (data.length) {
      const temp = handleImagesType(data);
      handleUploads(temp);
      await db.collection("users").doc(firebase.auth().currentUser.uid).update({
        images: imagesUrl,
      });
    }
  };

When the user presses the button to submit the images:当用户按下按钮提交图像时:

  onPress={() => {
            pushDataHandler(images);
            dispatch(pullUserData()); //Pulling all the data of a user from DB to a redux state
  }}

Here is a complete example that was done by OGcodes using the direct call to Cloudinary Rest API together with the ImagePicker component .这是OGcodes使用直接调用 Cloudinary Rest API 和ImagePicker 组件完成的完整示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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