Показать ответ React Native Redux Saga API

1

Я изучаю/работаю с React Native в течение пары недель, и я пытаюсь понять работу с Redux и Redux-Sagas. Я пробовал исследовать это в течение нескольких дней и (думал), что я все это понял, но, к сожалению, я все еще боюсь. Вот некоторые ресурсы, которые я прочитал и попытался:

https://shift.infinite.red/using-redux-saga-to-simplify-your-growing-react-native-codebase-2b8036f650de

https://hackernoon.com/moving-api-requests-to-redux-saga-21780f49cbc8

Я использую шаблон Ignite-CLI для создания приложения, которое запрашивает API для данных о погоде. Запрос API работает при использовании регулярной функции api.get() из apisauce но я не могу заставить действия Redux Saga возвращать данные. Я думаю, что я просто недостаточно понимаю концепцию.

Вот мой файл Api.js который использует apisauce для извлечения данных JSON из заданных параметров (это работает отлично)

/App/Services/Api.js

// a library to wrap and simplify api calls
import apisauce from 'apisauce'

// our "constructor"
const create = (baseURL = 'https://my-api-url.com/api/') => {

  const apiId = 'xxxxxxx'
  const apiKey = 'xxxxxxxxxxxxxxxxx'
  const resortKey = 'xxxxxx'
  const apiParams = resortKey + '?app_id=' + apiId + '&app_key=' + apiKey

  const api = apisauce.create({
    // base URL is read from the "constructor"
    baseURL,
    // here are some default headers
    headers: {
      'Cache-Control': 'no-cache'
    },
    // 10 second timeout...
    timeout: 10000
  })

  const getReport = () => api.get(apiParams)

  return {
    getReport,
  }
}

// let return back our create method as the default.
export default {
  create
}

Ignite CLI имеет удивительный генератор, который автоматически генерирует действия редукции и саги. Вот те сгенерированные файлы:

/App/Redux/SnowReportRedux.js (действия Redux)

import { createReducer, createActions } from 'reduxsauce'
import Immutable from 'seamless-immutable'

/* ------------- Types and Action Creators ------------- */

const { Types, Creators } = createActions({
  snowReportRequest: ['data'],
  snowReportSuccess: ['payload'],
  snowReportFailure: null
})

export const SnowReportTypes = Types
export default Creators

/* ------------- Initial State ------------- */

export const INITIAL_STATE = Immutable({
  data: null,
  fetching: null,
  payload: null,
  error: null
})

/* ------------- Reducers ------------- */

// request the data from an api
export const request = (state, { data }) =>
  state.merge({ fetching: true, data, payload: null })

// successful api lookup
export const success = (state, action) => {
  const { payload } = action
  return state.merge({ fetching: false, error: null, payload })
}

// Something went wrong somewhere.
export const failure = state =>
  state.merge({ fetching: false, error: true, payload: null })

/* ------------- Hookup Reducers To Types ------------- */

export const reducer = createReducer(INITIAL_STATE, {
  [Types.SNOW_REPORT_REQUEST]: request,
  [Types.SNOW_REPORT_SUCCESS]: success,
  [Types.SNOW_REPORT_FAILURE]: failure
})

/App/Sagas/SnowReportSagas.js

import { call, put } from 'redux-saga/effects'
import SnowReportActions from '../Redux/SnowReportRedux'

export function * getSnowReport (api, action) {
  const { data } = action
  // make the call to the api
  const response = yield call(api.getReport, data)

  // success?
  if (response.ok) {
    yield put(SnowReportActions.snowReportSuccess(response.data))
  } else {
    yield put(SnowReportActions.snowReportFailure())
  }
}

Затем, следуя пример они предоставляют, я добавил SnowReportActions из SnowReportRedux.js и getSnowReport функции от SnowReportSagas.js к функции корневых саг как таковые:

//...imports & constants

export default function * root () {
  yield all([
    // some sagas only receive an action
    takeLatest(StartupTypes.STARTUP, startup),

    // some sagas receive extra parameters in addition to an action
    takeLatest(SnowReportTypes.SNOW_REPORT_REQUEST, getSnowReport, api)
  ])
}

Теперь вот где я запутался; Как я могу называть эти действия отправки в своих компонентах или экранах? Я понимаю, что мне нужно import SnowReport Actions from '../Redux/SnowReportRedux и mapDispatchToProps но я не могу получить отправку для отправки... Вот некоторые части с одного из моих экранов:

/App/Containers/ResortReportScreen.js

//.. constructor

componentDidMount () {
  this.props.getSnowReport();
}

// .. render() / close component

const mapDispatchToProps = (dispatch) => {
  return {
    getSnowReport: () => dispatch({ type: SnowReportActions.snowReportRequest() })
  }
}

export default connect(null, mapDispatchToProps)(ResortReportScreen)

Когда срабатывает функция componentDidMount() он должен dispatch действие SnowReportActions.snowReportRequest(), правильно? Всякий раз, когда я использую console.log() чтобы вернуть ответ этого действия, он не заканчивает стрельбу. Что я здесь делаю неправильно? Как я могу получить данные из моего запроса API для отображения при использовании actions?

sagaMiddleware моя sagaMiddleware и reducers. Если нужно показать, что это просто спросить.

  • 0
    Оформите мой репо здесь с образцом примера.
Теги:
react-native
redux
redux-saga

1 ответ

0

Функция SnowReportActions.snowReportRequest() - это создатель действия, который возвращает действие, которое вы должны отправить. Вы можете исправить свой код следующим образом:

const mapDispatchToProps = (dispatch) => {
  return {
    getSnowReport: () => dispatch(SnowReportActions.snowReportRequest())
  }
}

Вы даже можете упростить свой код, используя объект вместо метода для mapDispatchToProps (https://github.com/reactjs/react-redux/blob/master/docs/api.md)

const mapDispatchToProps = {
    getSnowReport: SnowReportActions.snowReportRequest
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню