2017-06-12 67 views
1

我有一个使用redux体系结构的相对简单的React应用程序,出于某种原因,其中一个状态属性正在更改为承诺。React将状态键变为承诺

我最终会尝试从数据库中提取数据以用作数据,但我以硬编码数据开始。我不明白为什么在这个世界上,到达布局/图表/索引组件时为什么它已经变成了一个Promise?根据我的分析,我没有在应用程序中包含任何api/async功能。我已经包含了所有我认为与问题相关的文件。我已经尝试过在各个地方使用console.logging这个州,我似乎无法确定州政府何时或为什么决定改变承诺。任何帮助将非常感激。

GitHub项目回购here

app.js

import 'babel-polyfill'; 
import React from 'react'; 
import { render } from 'react-dom'; 
import { browserHistory } from 'react-router'; 
import { syncHistoryWithStore } from 'react-router-redux'; 
import { AppContainer } from 'react-hot-loader'; 
import configureStore from './store/configureStore'; 
import Root from './containers/Root'; 

const initialState = { 
    Charts: { 
     PieChart: { 
      data: { 
       failed: false, 
       isfetching: false, 
       contains: null 
      }, 
      msg: 'Preparing to fetch', 
      width: '100%', 
      height: '30vh', 
      options: { 
       title: 'Lateness of things', 
       backgroundColor: '#fff', 
       titlePosition: 'none', 
       pieHole: 0.7, 
       pieSliceTextStyle: { 
        color: 'black', 
       }, 
      } 
     }, 
     BarChart: { 
      chartType: 'BarChart', 
      width: '100%', 
      height: '30vh', 
      data: [ 
       ['Type', 'On time', 'Late', { role: 'annotation' }], 
       ['Child', 4, 18, ''], 
       ['Fire/EV/Body', 18, 21, ''], 
       ['Truck', 49, 92, ''], 
       ['Off-Highway/UTV', 18, 62, ''], 
       ['Bus/Coach/WTORS', 5, 8, ''], 
       ['Other', 11, 23, ''] 
      ], 
      options: { 
       isStacked: true, 
       height: 300, 
       legend: {position: 'top'}, 
       hAxis: {minValue: 0} 
      } 
     } 
    } 
}; 
const store = configureStore(initialState); 
const history = syncHistoryWithStore(browserHistory, store); 

render(
    <AppContainer> 
     <Root store={store} history={history}/> 
    </AppContainer>, 
    document.getElementById('root'), 
); 

if(process.env.NODE_ENV !== 'production' && module.hot) { 
    module.hot.accept('./containers/Root',() => { 
     const NewRoot = require('./containers/Root').default; 
     render(
      <AppContainer> 
       <NewRoot store={store} history={history}/> 
      </AppContainer>, 
      document.getElementById('root'), 
     ); 
    }); 
} 

reducer.js

import { routerReducer as routing } from 'react-router-redux'; 
import { combineReducers } from 'redux'; 
import * as types from '../actions/types'; 

const Charts = async (state = {}, action) => { 
    switch(action.type) { 
     case types.PIE_DATA_LOADING: 
      return {...state, PieChart: {isfetching: true, contains: null, failed: false}}; 
     default: 
      return state; 
    } 
}; 


const rootReducer = combineReducers({ 
    Charts, 
    routing, 
}); 

export default rootReducer; 

容器/ Charts.js

import MainChart from './../components/layout/charts'; 
import {connect} from 'react-redux'; 
import { startPieDataLoad } from './../actions'; 

const mapStateToProps = (state) => { 
    return { 
     Charts: state.Charts, 
    }; 
}; 

const mapDispatchToProps = (dispatch) => { 
    return { 
     loadingPieChartData:() => { 
      return dispatch(startPieDataLoad()); 
     } 
    }; 
}; 


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

组件/布局/图表/ index.js

import React from 'react'; 
import classNames from 'classnames'; 
import TotalChanges from './TotalChanges'; 
import ChangesByFunctionalGroups from './ChangesByFunctionalGroups'; 
import PropTypes from 'prop-types'; 

const MainChart = ({Charts}) => { 
    const BarChartData = Charts.BarChart; 
    const PieChartData = Charts.PieChart; 
    const PieChart = (!PieChartData.data.isfetching === false) ? (<TotalChanges chartData={PieChart} />) : (<div>{PieChartData.msg}</div>); 
    return (
     <div className={classNames('mainWindow')}> 
      <div className={classNames('row')}> 
       <div className={classNames('col-sm-4')}> 
        {PieChart} 
       </div> 
       <div className={classNames('col-sm-4')}> 
        <ChangesByFunctionalGroups chartData={BarChartData} /> 
       </div> 
       <div className={classNames('col-sm-4')}> 
       </div> 
      </div> 
     </div> 
    ); 
}; 

MainChart.propTypes = { 
    Charts: PropTypes.object, 
    loadingPieChartData: PropTypes.func 
}; 

export default MainChart; 

configureStore.js

import { createStore } from 'redux'; 
import rootReducer from '../reducers'; 

export default function configureStore(initialState) { 
    return createStore(
     rootReducer, 
     initialState 
    ); 
}; 

action.js

import * as types from './types'; 
import fetch from 'isomorphic-fetch'; 
export function example(filter) { 
    return { 
     type: types.FILTER, 
     filter, 
    }; 
} 

export function startPieDataLoad() { 
    return { 
     type: types.PIE_DATA_LOADING 
    }; 
}; 

export function finishPieDataLoad(data) { 
    return { 
     type: (data.err === true) ? types.PIE_DATA_LOADED_FAIL : types.PIE_DATA_LOADED_SUCCESS, 
     data: data.msg 
    }; 
}; 


export function fetchPieChartData() { 
    return (dispatch) => { 
     dispatch(startPieDataLoad); 
     return fetch('http://localhost:3001/cm/piechart').then(response => response.json()).then(json => dispatch(finishPieDataLoad(json))); 
    }; 
}; 
+0

后不'dispatch'返回一个承诺? –

+0

你可以发布你的商店配置(小提琴/回购会很好)吗?我认为这是一个中间件问题。 @CooperCampbell – John

+1

它不应该由我的理解,除非你正在实施thunk中间件什么的。无论哪种方式,我的应用程序甚至没有时间触发返回承诺的函数,组件第一次接收图表时,它是一个承诺。另外,我不认为这个派送回复承诺会混乱状态中的图表关键字,是吗? @DanielB –

回答

1

问题是我宣布行动作为异步函数,导致它返回一个承诺。我没有意识到那是为什么花了我三个小时才找到它的原因。

的问题是reducer.js

import { routerReducer as routing } from 'react-router-redux'; 
import { combineReducers } from 'redux'; 
import * as types from '../actions/types'; 

const Charts = (state = {}, action) => { 
    switch(action.type) { 
     case types.PIE_DATA_LOADING: 
      return {...state, PieChart: {isfetching: true, contains: null, failed: false}}; 
     default: 
      return state; 
    } 
}; 


const rootReducer = combineReducers({ 
    Charts, 
    routing, 
}); 

export default rootReducer; 

注缺乏异步的图表=

+0

不要忘记标记为答案。好工作伙伴。 – John

+0

它不会让我再过两天,非常感谢你帮助我。我疯狂地盯着它想知道为什么在这个世界上它决定随机回复承诺。你确定你不想要信用吗? @John –

+0

当然,你的答案是,你值得信任。 – John

1

首先第一件事情。在Redux中,你永远不会改变状态。在您的减速器使用object.assign

case types.PIE_DATA_LOADING: 
     return {...state, 
      Object.assign({}, {PieChart: {isfetching: true, contains: null, failed: false}}) 
+0

Nvm。我看看回购,并调试它。然后生病发布我所有的建议更改。 – John

+0

谢谢,我还认为传播语法否定了使用Object.assign()的必要吗?我无论如何都做了改动 –

+0

我发现了这个错误。这是减速机有讨厌的异步,我没有意识到我的朋友补充说。这导致函数返回一个承诺而不是新的状态。感谢您帮助我,并期待它,我希望我不会浪费太多时间。如果你想发布一个建议删除async关键字的答案,我会选择它作为正确的 –