2017-10-11 84 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