Как реализовать useMutation из реагирующего запроса в handleSubmit

Я попытался переписать эту функцию отправки, чтобы использовать ответный запрос useMutation, но я получаю ошибки. Кто-нибудь знает, как изменить это, чтобы оно было написано с помощью useMutation. Большое спасибо за каждую подсказку и каждый ответ на этот вопрос.

async function handleSubmit(e) {
    e.preventDefault();
    try {
      if (file) {
        // if file is set send it to cloudinary api
        const url = `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/upload`;
        loading(true);
        const formData = new FormData();
        formData.append("file", file);
        formData.append("upload_preset", UPLOAD_PRESET);

        const res = await fetch(url, {
          method: "POST",
          body: formData,
        });
        // get data and pull out 1000w image url
        const data = await res.json();
        const fileUrl = await data.eager[0].secure_url;
        console.info(fileUrl);
        setError("");
        if (album.trim() !== "" && color.trim() !== "" && fileUrl) {
          // Craeting Date form
          const albumData = new FormData();
          albumData.append("name", album);
          albumData.append("bckImgUrl", fileUrl);
          albumData.append("color", color);
          // change albumData to json
          const object = {};
          albumData.forEach((value, key) => (object[key] = value));
          // sending data to /api/v1/albums
          const res = await fetch(`${SERVER_API}/api/v1/albums`, {
            method: "POST",
            body: JSON.stringify(object),
            headers: {
              "Content-Type": "application/json",
            },
          });
          if (!res.ok) {
            const message = `An error has occured: ${res.status}`;
            setError(message);
          }
          const data = await res.json();
          const id = await data.data._id;
          loading(false);
          history.push(`/albums/${id}`);
        } else {
          setError("Please enter all the field values.");
        }
      } else {
        setError("Please select a file to add.");
      }
    } catch (error) {
      error.response && setError(error.response.data);
    }
  }

проверьте это, там есть описание как заливать файлы с помощью мутации

Robert 21.12.2020 21:39

@Robert, код, который я публикую, работает, но я не знаю, как его изменить с помощью useMutation, в этом проблема.

Kuba Kluzniak 21.12.2020 21:43
chat.stackoverflow.com/rooms/226261/usemutation-with-kuba тут можно немного поговорить
Robert 21.12.2020 21:56
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
3
7 846
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

небольшое предложение по рефакторингу :)

import React from "react";
import { useHistory } from "react-router-dom";
import { UPLOAD_PRESET, CLOUD_NAME, SERVER_API } from "../../config";

// to don't redefine this function on each rerender they can be defined out of component
const uploadImage = async file => {
    const url = `https://api.cloudinary.com/v1_1/${CLOUD_NAME}/upload`;
    const formData = new FormData();
    formData.append("file", file);
    formData.append("upload_preset", UPLOAD_PRESET);

    const res = await fetch(url, {
        method: "POST",
        body: formData,
    });

    if (!res.ok) {
        throw new Error(`Can't upload image. ${res.status}`)
    }

    const data = await res.json();
    return await data.eager[0].secure_url;
}

const createAlbum = async data => {
    const res = await fetch(`${SERVER_API}/api/v1/albums`, {
        method: "POST",
        body: JSON.stringify(data),
        headers: {
            "Content-Type": "application/json",
        },
    });

    if (!res.ok) {
        throw new Error(`An error has occurred: ${res.status}`)
    }

    const json = await res.json();
    return json.data._id;
}


const Form = ({ file, loading: setLoading, setError, album, color, children }) => {
    let history = useHistory();

    const clearError = () => setError("")
    
    const handleSubmit = async e => {
        e.preventDefault();
        clearError();
        try {
            if (!file) {
                throw new Error("Please select a file to add.");
            }

            if (!album.trim() || !color.trim()){
                throw new Error("Please enter all the field values.");
            }

            setLoading(true);

            const fileUrl = await uploadImage(file);

            const data = {
                "name": album,
                "bckImgUrl": fileUrl,
                "color": color
            };

            const albumId = await createAlbum(data);

            history.push(`/albums/${albumId}`);

        } catch (error) {
            setError(error.message);
        } finally {
            setLoading(false)
        }
    }


    return <form onSubmit = {handleSubmit}>{children}</form>
}

export default Form

@KubaKluzniak защищает размер изображения примерно так npmjs.com/package/browser-image-compression

Robert 22.12.2020 15:39

я использую useDropzone, и он встроен в этот файл .

Kuba Kluzniak 22.12.2020 18:26

Можете ли вы реализовать useMutation из react-query. Я ищу это.

Pranat Pannao 21.04.2021 07:15

@PranatPannao Разобрались?

Oliver D 26.04.2021 00:49

@OliverD посмотри мой новый ответ. Я думаю, это должно тебе помочь.

Randall 26.04.2021 15:35
Ответ принят как подходящий

Что-то вроде того. Как можно проще

Codesandbox ссылка на демо

import { Fragment, useState } from "react";
import axios from "axios";
import { useMutation } from "react-query"; 

const senRequest = async () => {
  return await axios.get("https://jsonplaceholder.typicode.com/posts");
};

export default function App() {
  const [val, setVal] = useState("");
  const [result, setResult] = useState([]);

  const { mutate } = useMutation(senRequest); // if you need to send data configure it from here
  const handleSubmit = (e) => {
    e.preventDefault();
    mutate(senRequest, { // And send it in here.
      onSuccess: ({ data }) => {
        setResult(data.slice(0, 5));
      }
    });
  };
  return (
    <div className = "App">
      <form onSubmit = {handleSubmit}>
        <input value = {val} onChange = {(e) => setVal(e.target.value)} />
        <button type = "submit">Submit</button>
      </form>
      {result.map((el) => (
        <Fragment key = {el.id}>
          <div
            style = {{
              width: "100%",
              borderBottom: "1px solid gray"
            }}
          >
            <span>{el.title}</span>
            <span>{el.body}</span>
          </div>
        </Fragment>
      ))}
    </div>
  );
}

Другие вопросы по теме