Состояние реакции useReducer не обновляется правильноJavascript

Форум по Javascript
Ответить
Anonymous
 Состояние реакции useReducer не обновляется правильно

Сообщение Anonymous »

Я столкнулся с проблемой в React: мне нужно загрузить несколько изображений одно за другим. Для этого я создал своего рода очередь, в которой, когда пользователь выбирает изображение, оно добавляется в очередь, и очередь обрабатывает его, загружая изображение в s3, и возвращает загруженный URL-адрес и обновленный статус. Вот код для этого:
import { uploadToS3 } from '~/utils/s3Upload';
import { PPFInspectionImage } from '~/context/PPFInspectionContext';

type StatusCallback = (
status: PPFInspectionImage['uploadStatus'],
serverUrl?: string,
key?: string
) => void;

interface QueueItem {
image: PPFInspectionImage;
partId: number;
onStatusChange: StatusCallback;
}

export class UploadManager {
private static instance: UploadManager;
private uploadQueue: QueueItem[] = [];
private isProcessing = false;
private maxConcurrent = 2;
private token: string;

private constructor(token: string) {
this.token = token;
}

static getInstance(token: string): UploadManager {
if (!UploadManager.instance || UploadManager.instance.token !== token) {
UploadManager.instance = new UploadManager(token);
}
return UploadManager.instance;
}

addToQueue(image: PPFInspectionImage, partId: number, onStatusChange: StatusCallback) {
this.uploadQueue.push({ image, partId, onStatusChange });
this.processQueue();
}

private async processQueue() {
if (this.isProcessing) return;
this.isProcessing = true;

try {
while (this.uploadQueue.length > 0) {
const batch = this.uploadQueue.splice(0, this.maxConcurrent);
await Promise.all(batch.map((item) => this.uploadImage(item)));
}
} catch (error) {
console.error('Error processing queue:', error);
} finally {
this.isProcessing = false;
}
}

private async uploadImage({ image, partId, onStatusChange }: QueueItem) {
onStatusChange('uploading');

try {
const response = await uploadToS3({
uri: image.localUri,
token: this.token,
inspectionType: 'ppf',
});

const serverUrl = `https://${process.env.EXPO_PUBLIC_BUCKET_NAME}.s3.${process.env.EXPO_PUBLIC_BUCKET_REGION}.amazonaws.com/${process.env.EXPO_PUBLIC_PPF_FOLDER}/${response.fileName}`;

onStatusChange('completed', serverUrl, response.key);
} catch (error) {
console.error('Upload failed:', error);
onStatusChange('failed');

// Add back to queue if retries remaining
if ((image.retryCount || 0) < 3) {
this.uploadQueue.push({
image: { ...image, retryCount: (image.retryCount || 0) + 1 },
partId,
onStatusChange,
});
}
}
}

// Method to retry failed uploads
retryUpload(image: PPFInspectionImage, partId: number, onStatusChange: StatusCallback) {
this.addToQueue({ ...image, retryCount: 0 }, partId, onStatusChange);
}
}

теперь дело в том, что я хочу обновить состояние после того, как эта очередь завершит обработку изображения, для которого у меня есть statusCallback, и в этом обратном вызове состояния я вызываю действие useReducer вот так
// Start background upload
UploadManager.getInstance(token).addToQueue(newImage, partId, (status, serverUrl, key) => {
dispatch({
type: 'UPDATE_IMAGE_STATUS',
payload: { partId, id: newImage.id, status, serverUrl, key },
});
});

Проблема в том, что если я добавляю изображения медленно, они обрабатываются правильно. Состояние также обновляется правильно, но когда я быстро добавляю изображения одно за другим, очередь обрабатывает их, загружает и возвращает правильные полные статусы, но когда состояние обновляется несколько раз, иногда статус не устанавливается правильно, что приводит к статус одного или двух изображений все еще установлен на загрузку или ожидание, но на самом деле они загружены успешно.
вот мой редуктор:
case 'UPDATE_IMAGE_STATUS': {
const part = state.faults[action.payload.partId];
if (!part) return state;

return {
...state,
faults: {
...state.faults,
[action.payload.partId]: {
...part,
images: part.images.map((img) =>
img.id === action.payload.id
? {
...img,
uploadStatus: action.payload.status,
serverUrl: action.payload.serverUrl,
key: action.payload.key,
}
: img
),
},
},
};
}


Подробнее здесь: https://stackoverflow.com/questions/793 ... -correctly
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»