2017-10-11 25 views
1

我目前正在使用Redux作爲數據管理系統構建React應用程序。我遇到了一個問題,我需要在從web-socket派發事件時更新應用程序(網頁)中的組件。流程如下:從外部API更新Redux店面

API Server push change -> Redux action is called -> Component that is effected by this update, is rebuild/re rendered. 

但是流的中間和最後部分是我迷路的地方。在調用動作時,儀表板是而不是重新創建/重新呈現。

我完全是React和Redux的新手。

Store.js

import { applyMiddleware, createStore } from 'redux'; 

import {createLogger} from "redux-logger"; 
import thunk from 'redux-thunk' 
import promise from 'redux-promise-middleware' 


import reducers from './reducers'; 

const middleware = applyMiddleware(promise(), thunk, createLogger()); 

export default createStore(reducers, middleware); 

DashboardReducer.js

const initState = { 
dashboard: [], 
fetching: false, 
fetched: false, 
error: null 
} 
export default function reducer(state = initState, action) { 
    switch (action.type) { 
    case "FETCH_DASHBOARD": 
    { 
     return { 
     ...state, 
     fetching: true 
    } 
    } 
    case 'FETCH_DASHBOARD_REJECTED': 
    { 
     return { 
     ...state, 
     fetching: false, 
     error: action.payload 
     } 
    } 
    case 'FETCH_DASHBOARD_FULFILLED': 
    { 
     return {fetching: false, fetched: true, dashboard:action.payload.dashboard} 
    } 
    case 'UPDATEING_SYSTEM': 
    { 
     return Object.assign({}, state, {dashboard: action.payload.dashboard}); 
    } 
    default: 
    break; 
} 
return state; 
} 

DashboardActions.js

import io from 'socket.io-client' 
    import UniversalCookie from 'universal-cookie'; 
    const cookies = new UniversalCookie(); 
    //CHANGE URL FOR PRODUCTION 
    //----------------------------------------- 
    const socket = io.connect('http://localhost:8080'); 
    //----------------------------------------- 
    export function fetchDashboard() { 
    return function(dispatch) { 
     socket.emit("get dashboard", {cookie:cookies.get("**********")}); 
     socket.on("return dashboard", function(jDashboard) { 
    dispatch({ 
     type: 'FETCH_DASHBOARD_FULFILLED', 
     payload: { 
     dashboard: jDashboard.dashboard 
     } 
    }); 
    }); 
    socket.on("errored", function(data) { 
    console.log(data); 
    dispatch({type: 'FETCH_DASHBOARD_REJECTED', payload: data}); 
    }); 
    socket.on("updating systems", function(data) { 
    console.log("updating...", data); 
    dispatch({ 
     type: 'UPDATEING_SYSTEMS', 
     payload: { 
     dashboard: data.updatedSystems 
     } 
    }); 
    }); 
} 
} 

儀表板組件

import React, {Component} from 'react'; 
import './Dashboard.css'; 
import CollectionContainer from '../CollectionContainer/CollectionContainer'; 
import {fetchDashboard} from '../../actions/dashboardAction'; 
import {connect} from "react-redux"; 

@connect((store) => { 
    return {dashboard: store.dashboardReducer.dashboard}; 
}) 
export default class Dashboard extends Component { 
    componentWillMount() { 
    this.props.dispatch(fetchDashboard()); 
    } 

    render() { 
    return (
     <div className="App"> 
     <div className="Head">HEADER</div> 
     <div className="CollectionContainer"> 
      <CollectionContainer dashboard={this.props.dashboard}/> 
     </div> 
     </div> 
    ); 
    } 
} 

開發工具剪斷 The action is called, but nothing happens

我認爲,問題出在減速,但我不知道。

最佳方案是僅更新受影響狀態的子對象。截至目前,該州的整個儀表板支柱都發生了變化。

UPDATE

我現在已經湊了一點周圍的代碼,並更改了後臺服務器給我更多的數據,因此,它應該是更容易找到「系統」,我需要更改。現在來的實際改變狀態的問題。這就是我現在有

DashboardReducer.js

const initState = { 
    dashboard: [], 
    fetching: false, 
    fetched: false, 
    error: null 
} 
export default function reducer(state = initState, action) { 
    switch (action.type) { 
    case "FETCH_DASHBOARD": 
     return { 
     ...state, 
     fetching: true 
     } 

    case 'FETCH_DASHBOARD_REJECTED': 
     return { 
     ...state, 
     fetching: false, 
     error: action.payload 
     } 

    case 'FETCH_DASHBOARD_FULFILLED': 
     return {fetching: false, fetched: true, dashboard: action.payload.dashboard} 

    case 'UPDATEING_SYSTEM': 
     let shelveNr = action.payload.dashboard[0].shelve; 
     let collectionNr = action.payload.dashboard[0].collection; 
     let systemNr = action.payload.dashboard[0].system; 
     let status = action.payload.dashboard[0].status; 
     console.log(" Status: ", state.dashboard[shelveNr]); 
     let newState = Object.assign({}, state, { 
     ...state.dashboard[shelveNr].Collections[collectionNr].systems[systemNr].status, 
     status: status 
     }); 
     return newState; 

    default: 
     return state; 
    } 
} 
+0

在行動'UPDATEING_SYSTEM',你完全更換儀表板數據。你打算合併數據嗎? –

+0

從長遠來看,我想要:查找當前狀態已更改的數據(在本例中爲「系統」),然後使用從服務器推送的數據更新該「系統」。 – Lasse

+0

您是否看到數據來自「console.log(」updating ...「,data);」?我建議使用mapStateToProps/mapDispatchToProps。此鏈接可能有所幫助:http://redux.js.org/docs/faq/ReactRedux。html#react-not-rerendering –

回答

1

你的動作類型'UPDATEING_SYSTEMS'然而,在你減速,你有'UPDATEING_SYSTEM'。另外,你不需要大括號。

更新你的減速使case

case 'UPDATEING_SYSTEMS': 
    return Object.assign({}, state, {dashboard: action.payload.dashboard}); 
+0

謝謝,我會相應地更新這些功能。我一直盯着這一天,沒有注意到拼寫錯誤。 – Lasse

+1

@Lasse使用const ACTION_NAME ='UPDATING_SYSTEM'的原因,例如:) –

+0

剛剛檢查過。它會觸發重新渲染,但該頁面在該操作後保持空白。這就像國家沒有再次設置。 – Lasse