0

我一直在尝试向第三方 API 发出简单的 URL 请求。这是我正在进行的项目(https://github.com/JMStudiosJoe/ReactPractice/tree/JMStudiosReact)。我一直在看 Dan Abramov 视频,从 redux 文档和这个例子中遵循这个例子,似乎遗漏了一些小东西,因为日志显示我的 API 数据已被接收并发送到减速器,但由于某种原因状态没有得到发送回组件。以下是代码摘要:

//app.tsx: 从 react-redux 获取 store 并使用 Provider

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

从那里,我在 reducer 中所做的状态应该连同我获取的数据一起返回给组件,但事实并非如此。我将不胜感激任何建议或帮助,谢谢。

4

1 回答 1

1

目前,您正在为mapStateToProps传入一个空对象userAddressData和空字符串。address因此,您的组件将始终具有这些值。

您需要在 mapStateToProps 中指定数据位于状态树中的位置。

查看 reducer 的形状,查看数据在状态树中的位置,然后在 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 中的 key userAddressData。所以state.userAddressData指出这一点。这就是您将状态映射到道具的方式。

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

创建 store 时,从 index.js 导入 reducer 并将其作为第一个参数传递给createStore.

例子。

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

const store = createStore(
        reducers
)
于 2017-08-03T12:16:26.940 回答