我已经和React Native一起学习/工作了几个星期,而且我正在努力掌握与Redux和Redux-Sagas合作的问题。我已经尝试了几天研究这个问题并且(想)我已经掌握了它,但不幸的是我仍然在苦苦挣扎。以下是我阅读和尝试的一些资源:
https://hackernoon.com/moving-api-requests-to-redux-saga-21780f49cbc8
我正在使用Ignite-CLI样板来创建一个查询API以获取天气数据的应用。使用api.get()
中的常规apisauce
函数时,API请求会起作用,但我无法通过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's return back our create method as the default.
export default {
create
}
Ignite CLI有一个很棒的生成器,可以自动生成redux动作和sagas。以下是生成的文件:
/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
函数添加到根saga函数中:
//...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()
返回该动作的响应时,它都不会被触发。我在这做错了什么?如何在使用actions
时显示我的API请求中的数据?
我的sagaMiddleware
和reducers
都是由Ignite自动生成的。如果有必要展示那些只是问。
答案 0 :(得分: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
}