2017-10-04 43 views
0

我一直在研究/使用React Native幾個星期,現在我試圖掌握使用ReduxRedux-Sagas。我已經嘗試了幾天的研究,並且(想)我已經掌握了它,但不幸的是我還在掙扎。這裏有一些資源,我已閱讀並嘗試:Display React Native Redux Saga API響應

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請求在使用apisauce中的常規api.get()函數時起作用,但我無法獲得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 
} 

點燃CLI有一個真棒生成器,自動生成redux動作和sagas。下面是這些生成的文件:

/App/Redux/SnowReportRedux.js(終極版操作)

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()) 
    } 
} 

然後,遵循他們提供的示例,我將SnowReportRedux.js中的SnowReportActionsSnowReportSagas.js中的getSnowReport函數添加到roo t傳奇功能如下:

//...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/SnowReportReduxmapDispatchToProps,但我不能讓調度火...下面是我的屏幕之一幾塊:

/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()函數觸發它應該dispatchSnowReportActions.snowReportRequest()行動,對不對?無論何時我使用console.log()來返回該動作的響應,它都不會終止發射。我在這裏做錯了什麼?如何在使用actions時從我的API請求中獲取數據?

我的sagaMiddlewarereducers都是由Ignite自動生成的。如果有必要展示那些只是問。

+0

結帳[這裏]我的回購協議(HTTPS對象的方法甚至簡化代碼:// github.com/pritishvaidya/create-react-native-redux-app)和一個示例。 –

回答

0

函數SnowReportActions.snowReportRequest()是一個動作創建器,它返回一個必須發送的動作。您可以修復這樣的代碼:

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

可以使用,而不是爲mapDispatchToPropshttps://github.com/reactjs/react-redux/blob/master/docs/api.md

const mapDispatchToProps = { 
    getSnowReport: SnowReportActions.snowReportRequest 
}