Saya sedang belajar ReactTs dan saya sedang mengkode aplikasi dua komponen sederhana untuk Mengunggah file dan dengan permintaan lain mendapatkan kemajuan unggahan, tetapi saya tidak dapat menerima data kemajuan dari permintaan. Saya pikir useEffect tidak pernah menjalankan axios get request. Bagaimana bisa mengeksekusi banyak kali permintaan get untuk mendapatkan kemajuan 0-100? Terima kasih atas bantuan Anda!

Komponen Utama:

import axios from 'axios';
import React, { Fragment, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { transactionFileAction, uploadFileAction } from '../../actions/uploadFileAction';
import { RootStore } from '../../store';
import ProgressBar from '../progressBar/ProgressBar';

const UploadFile: React.FC = () => {
  const dispatch = useDispatch();
  const uploadFileStore = useSelector((state: RootStore) => state.uploadFile);

  const [file, setFile] = useState<FormData>();
  const [uploadProgress, setUploadProgress] = useState<number | undefined>(0);
  const [uploadStatus, setUploadStatus] = useState<boolean>(false);

  useEffect(() => {
    if (uploadStatus) setUploadStatus(false);
  }, [uploadStatus, uploadFileStore]);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files && e.target.files.length > 0) {
      const formData = new FormData();
      formData.append("file", e.target.files[0]);
      setFile(formData);
    }
  };

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    dispatch(uploadFileAction(file));
    setUploadStatus(true);
  };

  return (
    <Fragment>
      <form onSubmit={(e) => handleSubmit(e)}>
        <label>Notes</label>
        <input
          type="file"
          name="file"
          accept=".pdf,.doc,.docx,.xls,.xlsx"
          onChange={(e) => handleChange(e)}
        />
        <button type="submit">Agregar</button>

        {uploadFileStore.UploadFileResponse?.message ? (
          <p>{uploadFileStore.UploadFileResponse?.message}</p>
        ) : null}
      </form>
      {uploadFileStore.UploadFileResponse?.transactionId ? (
        <ProgressBar
          transactionId={uploadFileStore.UploadFileResponse?.transactionId}
        />
      ) : null}
    </Fragment>
  );
};

export default UploadFile;

Komponen Kemajuan Unggah:

import axios from 'axios';
import React, { useEffect, useState } from 'react';

interface Props {
  transactionId: string | undefined;
}

const ProgressBar: React.FC<Props> = ({ transactionId }) => {
  const [uploadProgress, setUploadProgress] = useState<number | undefined>(0);
  console.log("entra");

  useEffect(() => {
    axios
      .get(`http://localhost:3000/file_parser/${transactionId}`)
      .then((response) => {
        setUploadProgress(response.data.progress);
      });
  }, [transactionId, uploadProgress]);

  return (
    <div>
      <p>{transactionId}</p>
      <p>Progreso: {uploadProgress && uploadProgress}</p>
    </div>
  );
};

export default ProgressBar;
1
Young Al Capone 12 Mei 2021, 22:04

1 menjawab

Jawaban Terbaik

Karena Anda perlu membuat permintaan dan ini tidak akan memicu rendering ulang yang lain satu kali karena transaksi hanya akan memanggil satu kali, maka Anda dapat melakukannya melalui interval waktu penggunaan untuk permintaan untuk maju setiap 1 detik misalnya ...

Mis: mari kita memiliki kait khusus useInterval:

import React, { useEffect, useRef } from 'react';

const useInterval = (callback, delay) => {
  const savedCallback = useRef();

  // Remember the latest callback.
  savedCallback.current = callback;

  // Set up the interval.
  useEffect(() => {
    function tick() {
      savedCallback.current();
    }
    if (delay !== null) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    }
  }, [delay]);
}

export default useInterval;

Kemudian di komponen saya, kita dapat menyebutnya:

  useInterval(() => {
    if(!transactionId) return;

    axios
      .get(`http://localhost:3000/file_parser/${transactionId}`)
      .then((response) => {
        setUploadProgress(response.data.progress);
      });
  }, 1000);

Pilihan lain:

Berdasarkan hasil dari api, kami terus memeriksa apakah respon kemajuan adalah 100 atau tidak, jika tidak maka memicu lagi ... misalnya:

  const [forceUpdate, setForceUpdate] = useState(null);
  useEffect(() => {
    axios
      .get(`http://localhost:3000/file_parser/${transactionId}`)
      .then((response) => {
        setUploadProgress(response.data.progress);
        if(response.data.progress !== 100){
          setForceUpdate(new Date());
        }
      });
  }, [transactionId, forceUpdate]);

Pilihan lain

Basis kerjanya pada peristiwa yang disarangkan dari permintaan api atau Socket atau opsi apa pun ...

1
Anees Hikmat Abu Hmiad 12 Mei 2021, 19:52