2017-08-02 84 views
0

我一直在嘗試向第三方API發出簡單的URL請求。這是我正在研究的項目(https://github.com/JMStudiosJoe/ReactPractice/tree/JMStudiosReact)。我一直在觀看Dan Abramov的視頻,其次是example from redux docsexample,並且由於日誌顯示我的API數據已收到並已發送給reducer,但由於某種原因,狀態不會被髮送回組件。 下面的代碼摘要:React Redux Thunk with Typescript製作api請求

//app.tsx:得到反應,終極版

import * as React from 'react' 
 
import * as ReactDOM from 'react-dom' 
 
import store from './redux/store/store' 
 
import { Provider } from 'react-redux' 
 
import { getAddressData } from './redux/actions/voteSmartActions' 
 
import {UIRouter, UIView, UISref, UISrefActive, pushStateLocationPlugin} from 'ui-router-react'; 
 
import NavigationBarComponent from './components/navigationBarComponent' 
 

 
store.dispatch(getAddressData('')) 
 

 
ReactDOM.render(
 
    <Provider store={store}> 
 
     <NavigationBarComponent userType='buyer' /> 
 
    </Provider>, 
 
    document.getElementById("root") 
 
);

有問題的部件被從projectsComponent.tsx文件中加載的存儲和使用提供

if(projectName == 'Vote Smart Locally') { 
 
     return (
 
      <VoteSmartLocallyComponent /> 
 
     ) 
 
}

//voteSmartLocallyComponent.tsx

import * as React from 'react' 
 
import { connect } from 'react-redux' 
 
import { getAddressData } from '../../redux/actions/voteSmartActions' 
 
import store from "../../redux/store/store" 
 
interface VoteSmartState { 
 
    address: string 
 
    userAddressData?: any 
 
} 
 
interface VoteSmartProps { 
 
    fetchAddressData: any 
 
} 
 
const API_KEY = 'AIzaSyCWhwRupMs7IeE4IrGEgHtT0Nt-IGZnP9E' 
 
const endURL = '&key='+ API_KEY 
 
const baseRepURL = 'https://www.googleapis.com/civicinfo/v2/representatives?address=' 
 
const baseElectionsURL = 'https://www.googleapis.com/civicinfo/v2/elections?alt=json&prettyPrint=true' 
 
class VoteSmartLocallyComponent extends React.Component<VoteSmartProps, VoteSmartState> { 
 
    constructor(props) { 
 
     super(props) 
 
     console.log(props) 
 
     this.state = { 
 
      address: '', 
 
      userAddressData: {} 
 
     } 
 
    } 
 
    removeSpacesAddPluses() { 
 
     return this.state.address.split(' ').join('+')  
 
    } 
 
    lookupAddress(event: React.MouseEvent<HTMLButtonElement>) { 
 
     event.preventDefault() 
 
     const address = this.removeSpacesAddPluses() 
 
     const fullRepURL = baseRepURL + address + endURL 
 
     const fullElectionsURL = baseElectionsURL + address + endURL 
 
     this.props.fetchAddressData(fullRepURL) 
 
      /* 
 
     store.subscribe(this.render) 
 
     store.dispatch({ 
 
      type: 'LOOKUP_ADDRESS', 
 
      payload: address 
 
     }) 
 
      */ 
 
    } 
 

 
    handleAddress(event: React.ChangeEvent<HTMLInputElement>) { 
 
     event.preventDefault() 
 
     const address = event.target.value 
 
     this.setState({ 
 
      address: address 
 
     }) 
 
    } 
 

 
    render() { 
 
     return (
 
     <div> 
 
      {console.log('log in the render method')} 
 
      {console.log(this.state)} 
 
      vote smart kids 
 
      need to connect the redux and suff to make request 
 
      <input 
 
       type='text' 
 
       placeholder='Address' 
 
       onChange={ e => this.handleAddress(e) } 
 
      /> 
 
      <button 
 
       onClick={ e => this.lookupAddress(e) } 
 
      > 
 
      Submit for info 
 
      </button> 
 
     </div> 
 
     ) 
 
    } 
 

 
} 
 

 
const mapStateToProps = (state) => { 
 
    return { 
 
     address: '', 
 
     userAddressData: {} 
 
    } 
 
} 
 
const mapDispatchToProps = (dispatch) => { 
 
    return { 
 
     fetchAddressData: (url) => dispatch(getAddressData(url)) 
 
    } 
 
} 
 
export default connect(mapStateToProps, mapDispatchToProps)(VoteSmartLocallyComponent)

我能夠調用this.props.fetchAddressData(fullRepURL)這就要求我的行動

//voteSmartActions.tsx

import {Action} from 'redux' 
 
import store from '../store/store' 
 
import axios from 'axios' 
 

 
interface VoteSmartAction<Action> { 
 
    type: string 
 
    payload?: any 
 
} 
 
const getAddressData = (fullURL: string) => { 
 
    return function(dispatch, getState) { 
 
     if (fullURL !== '') { 
 
      return axios.get(fullURL).then(function (response) { 
 
       dispatch(addressDataSuccess(response)) 
 
      
 
      }).catch(function (error) { 
 
        console.log(error) 
 
      }) 
 
     } 
 
    } 
 
} 
 
const addressDataSuccess = (addressData: any) => { 
 
    return { 
 
     type: 'HANDLE_RETURN_DATA', 
 
     payload: addressData, 
 
     addressData 
 
    } 
 
} 
 
export { 
 
    getAddressData, VoteSmartAction 
 
}

從那裏去我減速

//voteSmartReducer.tsx

import {Action} from 'redux' 
 
import {VoteSmartAction, getAddressData} from '../actions/voteSmartActions' 
 
import axios from 'axios' 
 
const INITIAL_STATE: any = { 
 
    address: '', 
 
    userAddressData: {} 
 
} 
 
const VoteSmartReducer = (state: any = INITIAL_STATE, action: VoteSmartAction<Action>): any => { 
 
    switch(action.type) { 
 

 
     case "HANDLE_RETURN_DATA": 
 
      console.log("in reducer handling return payload is") 
 
      const returnData = { 
 
       ...state, 
 
       userAddressData: action.payload 
 
      } 
 
      console.log(returnData) 
 
      
 
      return returnData 
 

 
     default: 
 
      return state 
 
    } 
 
} 
 
export default VoteSmartReducer

從那裏我在減速就狀態應與被返回到組件我提取的數據,但它不是。我將不勝感激任何建議或幫助,謝謝。

+0

也被下面的這篇文章,它關係到我的代碼,以及(https://stackoverflow.com/questions/39794895/how-do-i-make-an-http-request-in- react-redux) –

回答

1

目前,您在mapStateToProps中傳入空對象userAddressData和空字符串address。所以你的組件總是會有這些值。

您需要在mapStateToProps中指定數據位於狀態樹內。

查看縮減器的形狀,並查看數據在狀態樹內的位置,然後在mapStateToProps中按以下方式映射它。

index.js

import { combineReducers } from 'redux' 
import voteSmartReducer from './VoteSmartReducer' // assuming this is in same directory 
import someOtherReducer from './someOtherReducer' // example purposes 

export default combineReducers({ 
    userAddressData: voteSmartReducer, 
    otherExample: someOtherReducer 
}) 

正如你可以看到,由voteSmartReducer返回的數據被映射到combineReducers密鑰userAddressData。所以state.userAddressData指向這一點。這就是你將狀態映射到道具的方式。

const mapStateToProps = (state) => { 
    return { 
     userAddressData: state.userAddressData, 
     otherExample: state.otherExample 
    } 
} 

當您創建的商店,你導入從index.js減速,並在將它作爲第一個參數createStore

例子。

import { createStore } from 'redux' 
import reducers from './index.js' 

const store = createStore(
     reducers 
) 
+0

謝謝@meteorBuzz這一切現在變得更有意義了,並將reducer連接到組件,以繼續從狀態樹中傳輸數據。我不知道標記這個是否正確,因爲現在我可以在mapStateToProps函數中看到我想要的數據並正確地返回它,但由於某種原因,用於打印狀態的render方法中的日誌仍然是舊狀態,而不是新的那一個。這是一個新的問題嗎? –

+0

是的,我想我現在發現它,以及如何通過道具獲取我需要的狀態數據,提示是函數名稱mapStateToProps,然後我在render()方法中檢查this.props的內部,並且有我的數據謝謝@meteorBuzz –

+0

Your're歡迎@ JMStudios.jrichardson! – meteorBuzz

相關問題