2017-10-08 71 views
0

我試圖從我的API使用REDX傳奇獲取一些數據。不幸的是它失敗了,我收到Uncaught TypeError: this.props.fetchData is not a function。另外this.props.someInfo是未定義的。由於我正在做一些控制檯日誌,我看到沒有輸入功能getData。我認爲這意味着解僱這個行爲是有問題的。不幸的是,我不知道什麼可能是錯誤的或如何解決它。REDX傳奇,問題的機智連接()

createStore.js

import {createStore, applyMiddleware, compose} from 'redux'; 
import createSageMiddleware from 'redux-saga'; 

import rootReducer from '../reducers/index'; 
import rootSaga from './rootSaga'; 
// import {rootSaga} from '../sagas/FAQSaga'; 

const sagaMiddleware = createSageMiddleware(); 

export default function configureStore(initialState) { 
    const middleware = applyMiddleware(sagaMiddleware); 
    const store = createStore(
     rootReducer, 
     compose (
      middleware, 
      window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() // for displaying in google dev tools 
     ) 
    ); 

    sagaMiddleware.run(rootSaga); 

    return store; 
}; 

rootSaga.js

import { fork } from 'redux-saga/effects'; 
import FAQSaga from '../sagas/FAQSaga.js'; 

export default function * rootSaga() { 
    yield [ 
     fork(FAQSaga) 
    ]; 
} 

FAQSaga.js

import * as actions from '../actions/FAQActions'; 
import axios from 'axios'; 
import { call, put, take, fork } from 'redux-saga/effects'; 

export function* getData() { 
    try { 
     console.log('getdata'); 
     const response = yield call(axios.get, 'http://localhost:8080/rest/book/all'); 
     const data = yield response.json(); 
     yield put(actions.GET_FAQ.SUCCESS(data)); 
    } catch (e) { 
     console.log('erorr'); 
     console.log(e); 
     yield put(actions.GET_FAQ.FAILURE(e)); 
    } 
} 

export function* watchData() { 
    console.log('watchData'); 
    while (true) { 
     console.log('true'); 
     yield take(actions.GET_FAQ.REQUEST); 
     yield fork(getData); 
    } 
    // yield takeEvery(actions.GET_FAQ.REQUEST, getData); 
} 

function * FAQSaga() { 
    console.log('FAQSaga'); 
    yield [ 
     fork(watchData) 
    ]; 
} 

export default FAQSaga; 

FAQActions.js

import {REQUEST, SUCCESS, FAILURE, action} from './helpers'; 

const GET_FAQ_BASE = 'GET_FAQ_'; 
export const GET_FAQ = { 
    REQUEST: GET_FAQ_BASE + REQUEST, 
    SUCCESS: GET_FAQ_BASE + SUCCESS, 
    FAILURE: GET_FAQ_BASE + FAILURE 
}; 

const POST_FAQ_BASE = 'POST_FAQ_'; 
export const POST_FAQ = { 
    REQUEST: POST_FAQ_BASE + REQUEST, 
    SUCCESS: POST_FAQ_BASE + SUCCESS, 
    FAILURE: POST_FAQ_BASE + FAILURE 
}; 

export const getFAQ = { 
    request:() => action(GET_FAQ.REQUEST), 
    success: response => action(GET_FAQ.SUCCESS, {response}), 
    failure: error => action(GET_FAQ.FAILURE, {error}) 
}; 

export const postFAQ = { 
    request: data => action(POST_FAQ.REQUEST, {data}), 
    success: response => action(POST_FAQ.SUCCESS, {response}), 
    failure: error => action(POST_FAQ.FAILURE, {error}) 
}; 

FAQContainer.js

import React from 'react'; 

import { connect } from 'react-redux' 
import * as actions from '../../actions/FAQActions'; 

import FAQ from './FAQ'; 

function mapDispatchToProps(dispatch) { 
    return ({ 
     fetchData:() => {dispatch(actions.getFAQ.request)} 
    }) 
} 

function mapStateToProps(state) { 
    return ({ someInfo: "some info" + state}) 
} 

export default connect(mapStateToProps, mapDispatchToProps)(FAQ); 

FAQ.js

import React, {Component} from 'react'; 
import axios from 'axios'; 

// import { connect } from 'react-redux' 
// import * as actions from '../../actions/FAQActions'; 


class FAQ extends Component { 
    componentDidMount() { 
     console.log('this.props.someInfo'); 
     console.log(this.props.someInfo); 
     console.log('this.props.fetchData()'); 
     console.log(this.props.fetchData()) 
    } 

    render() { 
     return (
      <div> 
       <p>Here some Frequently Asked Questions will be displayed.</p> 
       {console.log('FAQ')} 
       { this.props.children } 
       <button type="button" onClick={this.postLoginData}> 
        post 
       </button> 
      </div> 
     ) 
    } 
} 

FAQ.propTypes = {}; 

export default FAQ; 
+0

您確定您在某些父組件中使用'FAQContainer'而不是'FAQ'嗎? – dostu

回答

0

與此代碼在FAQContainer.js

function mapDispatchToProps(dispatch) { 
    return { 
     fetchData() { 
      dispatch(actions.getFAQ.request); 
     } 
    }; 
} 

function mapStateToProps(state) { 
    return (state) => ({ 
     someInfo: "some info" + state; 
    }); 
} 
+0

不幸的是它沒有幫助。你有沒有其他建議? –

0

會轉而在道具創造一個功能,你可以簡單地映射dispatch到你的道具並直接從組件發送任何需要的操作:

function mapDispatchToProps(dispatch) { 
    return { 
    dispatch 
    }; 
} 

而在你的組件現在,你可以簡單地做:

componentDidMount() { 
    this.props.dispatch(actions.getFAQ.request); 
} 

而且由於調度恰恰是觸發一個動作,開始了Redux數據流,我不知道爲什麼你正在呼籲console.log你的調度呼叫的輸出。您無法以同步方式獲得異步API調用的結果,因此在將組件連接到redux時,應使用mapStateToProps進行映射。

另一種解決方案,我認爲將是有幫助的是使用bindActionCreators從終極版:

import { bindActionCreators } from 'redux'; 
import * as actionCreators from '../actions/youractions'; 

//... 

function mapDispatchToProps(dispatch) { 
    return { 
    actions: bindActionCreators(actionCreators, dispatch), 
    dispatch, 
    }; 
} 

它映射動作到你的道具。使用此解決方案,您不需要手動操作dispatch,它們將全部自動映射到您的道具。