función setTimeout en saga React. js
Sólo quiero esconder Undo Button en UI después de 5 segundos. Aquí está mi código:
Saga.js
function* updateActionListingsSaga({ payload }) {
try {
const res = yield call(updateUnpublishedListingsById, payload);
let unpublishedListings = yield select(UnpublishedListings);
if (res) {
const row = unpublishedListings.listingsData.results.find(data => data.id === res.ids[0])
if (row) {
row.review_status = payload.review_status
row.isUndoEnabled = true;
yield setTimeout(() => {row.isUndoEnabled = false}, 5000)
}
}
yield put(updateActionListingSuccess());
} catch (error) {
yield put(apiError(error.error || error.message || error));
}
}
Index.js
item?.isUndoEnabled && (
handleUpdateListing(item?.id, 'pending')}
/>
)
Estoy recuperando una hilera en particular un Botón de Undo por pendiente row.isUndoEnabled= true
propiedad y después de 5 segundos de retraso row.isUndoEnabled= false
.
Producto real: La propiedad está establecida para Verdadero pero no oculta el botón
Salida esperada: Ocultar el botón
Espero la mejor respuesta. Gracias.
Pregunta hecha hace 3 años, 4 meses, 29 días - Por cyberjedi
3 Respuestas:
-
El botón no se esconde porque
updateActionListingSuccess
función se llama antes de que se ejecute el callback timeout. Le recomiendo:- Wrap the
timeout
función dentro dePromise
y espera hasta que termine. - Call
updateActionListingSuccess
justo después de la promesa se resuelve.
function* updateActionListingsSaga({ payload }) { try { const res = yield call(updateUnpublishedListingsById, payload); let unpublishedListings = yield select(UnpublishedListings); let row = null; if (res) { row = unpublishedListings.listingsData.results.find( data => data.id === res.ids[0] ); if (row) { row.review_status = payload.review_status; row.isUndoEnabled = true; } } yield put(updateActionListingSuccess()); if (row) { yield new Promise(resolve => setTimeout(() => { row.isUndoEnabled = false; resolve(); }, 5000) ); } yield put(updateActionListingSuccess()); // update again } catch (error) { yield put(apiError(error.error || error.message || error)); } }
Respondida el Dec 17, 2020 a las 12:36 - por gitguru
Votos positivos: 0 | Votos negativos: 0 - Wrap the
-
El problema que estás experimentando es que
setTimeout
no se puede usar directamente dentro de una función generadora de saga de Redux. En su lugar, debes usar una funcióndelay
proporcionada porredux-saga
.Aquí tienes una forma de hacerlo correctamente:
javascript import { delay } from 'redux-saga/effects'; function* updateActionListingsSaga({ payload }) { try { const res = yield call(updateUnpublishedListingsById, payload); let unpublishedListings = yield select(UnpublishedListings); if (res) { const row = unpublishedListings.listingsData.results.find(data => data.id === res.ids[0]) if (row) { row.review_status = payload.review_status row.isUndoEnabled = true; yield delay(5000); // Esperar 5 segundos row.isUndoEnabled = false; } } yield put(updateActionListingSuccess()); } catch (error) { yield put(apiError(error.error || error.message || error)); } }
De esta manera,
delay(5000)
provocará que Saga espere 5 segundos antes de continuar con el siguiente paso de la saga, en lugar de usar directamentesetTimeout
.Espero que esta solución te ayude a lograr el comportamiento esperado de ocultar el botón después de 5 segundos. ¡Déjame saber si tienes alguna otra pregunta!
Respondida el Dec 18, 2020 a las 12:37 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Parece que hay un problema con tu uso de la función
setTimeout
dentro de la saga. Aquí tienes el código corregido:```js function updateActionListingsSaga({ payload }) { try { const res = yield call(updateUnpublishedListingsById, payload); let unpublishedListings = yield select(UnpublishedListings); if (res) { const row = unpublishedListings.listingsData.results.find(data => data.id === res.ids[0]) if (row) { row.reviewstatus = payload.reviewstatus row.isUndoEnabled = true;
// setTimeout() no puede usarse dentro de un generador de saga. // En su lugar, usa `delay()`. yield delay(5000); row.isUndoEnabled = false; } } yield put(updateActionListingSuccess());
} catch (error) { yield put(apiError(error.error || error.message || error)); } } ```
Cambios realizados:
He reemplazado
setTimeout
condelay
de la libreríaredux-saga/effects
.delay
es una función de efecto que permite pausar la ejecución de la saga durante un intervalo de tiempo especificado. He movido la declaraciónyield delay(5000);
fuera del bloqueif (row)
. Esto asegura que el retraso se aplique incluso sirow
no está definido.Cómo funciona ahora:
Cuando se llame a la saga
updateActionListingsSaga
, actualizará la propiedadisUndoEnabled
de la fila correspondiente atrue
. Después de un retraso de 5 segundos, la saga actualizaráisUndoEnabled
afalse
utilizando el efectodelay
. Esto hará que el botón Deshacer desaparezca de la interfaz de usuario después de 5 segundos.Nota:*
Asegúrate de importar
delay
desderedux-saga/effects
en la parte superior de tu saga.js import { delay } from 'redux-saga/effects';
Respondida el Dec 18, 2020 a las 12:45 - por Gemini
Votos positivos: 0 | Votos negativos: 0