Redux 异步请求问题(Thunk 中间件)

Redux Asynchronous Request Issue (Thunk Middleware)

所以我可能想多了这个问题,但我似乎无法让我的组件异步工作。

本质上,我使用 thunk 来分派一个操作,该操作将从本地服务器检索 JSON,一旦接收到,将其传递给 reducer 并更新状态,然后渲染组件。

相反,该组件将应用程序的初始状态接收为 {} 空对象,因此在我使用 map 呈现该组件时出现错误。

这是我拥有的:

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import thunk from 'redux-thunk';
import promise from 'redux-promise';

import App from './components/app';
import VotesContainer from './containers/votes-container';
import NewPoll from './containers/newpoll';
import VoteTemplate from './components/vote-template';
import Login from './components/auth/login';
import Signup from './components/auth/signup';
import reducers from './reducers/';

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(reducers, composeEnhancers(applyMiddleware(thunk)))

ReactDOM.render(
  <Provider store={store}>
    <Router history={browserHistory}>
      <Route path="/" component={App}>
        <IndexRoute component={VoteTemplate} />
        <Route path="allposts" component={VotesContainer} />
        <Route path="login" component={Login} />
        <Route path="signup" component={Signup} />
        <Route path="newpoll" component={NewPoll} />
      </Route>
    </Router>
  </Provider>
  , document.querySelector('#project'));

actions/index.js

import axios from 'axios';
const ROOT_URL = 'http://localhost:1234';
import { browserHistory } from 'react-router';
import { FETCH_VOTES, CAST_VOTE } from './types';

export function fetchVotes(){
  return function(dispatch){
    axios.get(`${ROOT_URL}/newpost`)
      .then(response => {
        console.log('Dispatch!!')
        dispatch({
          type: FETCH_VOTES,
          payload: response.data
        })
      })
  }
}

容器

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions'

class VotesContainer extends Component {
  componentDidMount(){
    this.props.fetchVotes()
  }
  renderCards(){
    return(
      <div className="col s12 m6 l4">
        <div className="card blue-grey darken-1">
          <div className="card-content white-text">
            <span className="card-title">Vote App Title #1</span>
            <p className="description">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
          </div>
          <div className="card-action">
            <a href="#">Results</a>
            <a href="#">Date Created</a>
          </div>
        </div>
      </div>
    )
  }
  render(){
    console.log(this.props.voteData)
    return(
      <main className="votes-container container">
        <div className="row">
          {this.props.voteData.map(this.props.voteData.vote)} <<======= gives error since it is null first before dispatch
        </div>
      </main>
    )
  }
}

function mapStateToProps(state){
  return {voteData: state.voteData};
}

export default connect(mapStateToProps, actions)(VotesContainer)

您应该根据您在组件中的预期设置商店的一些初始状态。
如果您不这样做,那么您不应该期望所有数据都在第一个 render 中。 fetch之后才会有数据,到时候你不妨在组件中加一些安全检查。