web-dev-qa-db-fra.com

Promesses dans redux-saga

J'ai trouvé la même question ici , mais sans réponse appropriée que je recherche.

Je développe une application simple avec des opérations CRUD. Sur la page d'édition, une fois le composant monté (componentDidMount()), l'application envoie une action pour récupérer les détails d'une publication spécifique:

dispatch({ type: FETCH_POST, id: 'post-id' })

J'utilise redux-saga et je veux que l'appel ci-dessus renvoie une promesse afin que je puisse accéder à la réponse de l'API.

En ce moment, sans rappel/promesse, j'ai fini par définir un nouvel état en magasin (comme post_edited) et le connecter/mapper aux accessoires dans le composant pour la page d'édition.

Quelle serait la meilleure façon possible de faire face à ce genre de situation?

8
Ming Soon

Pourriez-vous s'il vous plaît fournir plus d'informations sur votre problème? Je ne sais pas si je comprends bien votre problème, mais la pratique courante est:

API.js

function apiCallToFetchPost(id) {
  return Promise.resolve({name: 'Test});
}

postSaga.js

function* fetchPostSaga({id}) {
  try {
    const request = yield call(apiCallToFetchPost, id);
    // -> in post reducer we will save the fetched data for showing them later 
    yield put({type: FETCH_POST_SUCCESS, payload: request}); 
  } catch (error) {
    yield put({type: FETCH_POST_SUCCESS_FAILURE, error})
  }
}

export function* onBootstrap() {
  yield takeLatest(FETCH_POST, fetchPostSaga);
}
14
jukben

Il y a un paquet qui fait exactement ce que l'OP a demandé, c'est à dire que dispatch() peut retourner une promesse: @ Adobe/redux-saga-promise En l'utilisant, vous définissez une "action de promesse "créateur via:

import { createPromiseAction } from '@Adobe/redux-saga-promise'

export const fetchPostAction = createPromiseAction('FETCH_POST')

La dispatch() d'une "action de promesse" retournera une promesse:

await dispatch(fetchPostAction({ id: 'post-id' }))

La saga pourrait ressembler à:

import { call, takeEvery }        from 'redux-saga/effects'
import { implementPromiseAction } from '@Adobe/redux-saga-promise'

import { fetchPostAction } from './actions'

function * fetchPostSaga(action) {
  yield call(implementPromiseAction, action, function * () {
    const { id } = action.payload
    return yield call(apiCallToFetchPost, id)
  })
}

export function * rootSaga() {
  yield takeEvery(fetchPostAction, fetchPostSaga);
}

Il résoudra la promesse avec la valeur renvoyée par apiCallToFetchPost ou rejettera si apiCallToFetchPost génère une erreur. Il envoie également des actions secondaires avec la résolution/rejet auquel vous pouvez accéder dans un réducteur. Le paquet fournit middleware que vous devez installer pour le faire fonctionner.

(Avertissement, je suis l'auteur)

0
ronen