2017-06-12 66 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關鍵字的答案,我會選擇它作爲正確的 –