2016-08-01 52 views
1

我有一個Web套接字,它接受一個名爲PushMessage的對象並將它發送到一個React頁面,該頁面隨後會實時更新。這樣做的方式是用戶搜索他希望顯示的PushMessage,然後傳入。但是,現在發生的事情是,如果用戶搜索第一個PushMessage,則會顯示該消息,但如果他或然後她搜索另一個PushMessage,它們都顯示出來。我只想顯示其中的第二個。爲了做到這一點,我覺得我需要清理Redux存儲(將其返回到其初始空狀態)。但是,我無法弄清楚如何做到這一點。Clear Redux Store

我減速器由下式給出:

var Redux = require('redux'); 
var _ = require('lodash'); 

var pushNotificationDefaultState = {}; 


var pushMessageReducer = function(state, action) { 
    switch(action.type) { 
     case 'RECEIVED_PUSH_MESSAGE': 
      var obj = JSON.parse(action.PushMessage); 
      return _.assign({}, state, obj); 
     default: 
      if (typeof state === 'undefined') { 
       return pushNotificationDefaultState; 
      } 

      return state; 
    } 
}; 

module.exports = Redux.combineReducers({ 
    pushMessages: pushMessageReducer 
}); 

在我有分量:

function mapStateToProps(state) { 
    return state; 
} 


var AppContainer = connect(
    mapStateToProps, 
    null 
)(App); 

任何和所有幫助將升值。提前致謝。

+1

您不需要清除商店。你可以顯示PushMessage的reducer代碼嗎? –

+0

我已編輯添加減速器。謝謝。 – LivingRobot

+1

@ user5407287你真的應該在減速器狀態中有一個結構,而不是盲目地將一個行爲的結果傳遞給它。減速器的要點是要有一個清晰的結構,能夠巧妙地響應行動,而不僅僅是轉儲行動結果的地方。 –

回答

2

你可以通過很多方式實現這一點,我會告訴你我將如何接近它。讓我們來看看你的狀態馬上蝙蝠 - 因爲你使用的組合減速器要拆分的狀態,像這樣:

{ 
    pushMessages: { pushMessages state in here } 
} 

所以combineReducers當你想你的應用程序分割成一種「子狀態」是偉大的,思想在這種情況下,redux仍然是單店。現在你只有pushMessages的單子狀態。

我會採取組件,並設置一個操作來添加一條消息(最終可能會刪除一條消息)。我正在使用immutable.js,因爲我碰巧喜歡和它一起工作,所以IMO使它更好用,因爲無論如何,國家應該是不可改變的(再次,個人觀點)。

因此,這裏是你的減速:

var pushMessageReducer = function(state = immutable.Map(), action) { 
    if (action && action.type) { 
     switch (action.type) { 

      case actions. RECEIVED_PUSH_MESSAGE: 
       return state.update('messages', immutable.List(), 
        (oldMessages) => oldMessages.push(action.PushMessage) 
       ); 


      default: 
       return state; 
     } 
    } 
    return state; 
} 

所以這樣做是設置你的狀態,像這樣:

{ 
    pushMessages: { 
     messages: [ ... all your messages pushed in here] 
    } 
} 

由於您使用的組合異徑你的容器應訂閱到它的子狀態pushMessages,所以在你的組件中,你將有this.props.messages與你的消息數組。 (如果你還沒有訂閱這個子狀態,它只是this.props.pushMessages.messages。而顯示最後一個項目,你真正需要的是這樣的東西(這是使用lodash,你當然可以做到這一點在香草js或任何你想要的)

constructor(props) { 
    super(props); 
    this.getLastMessage = this.getLastMessage.bind(this); 
}  

    getLastMessage() { 
     return _.last(this.props.messages); 
    } 

    render() { 

    return(
     <div> 
      Last Message : {this.getLastMessage()) 
     </div> 
    ); 
    } 

所以,也許你不希望列表中包含所有內容,只顯示最後一個(我不確定你正在尋找什麼確切的商業邏輯),但你可以很容易地添加一個REMOVE_PUSH_MESSAGE動作,只需彈出或拼接(然後你可以顯示this.props.message沒有_.last),希望這會有所幫助!

編輯:

這裏是我將如何設置你的容器:

import immutable from 'immutable'; 
import { connect } from 'react-redux'; 
import Component from './component'; 
import * as actionCreators from './action-creators'; 

function mapStateToProps(state) { 
    const normalizedState = state.get('pushMessageReducer', immutable.Map()).toJS(); 

    return { 
     messages: normalizedState.messages 
    }; 
} 

function mapDispatchToProps(dispatch, ownProps) { 
    return { 
     myAction: actionCreators.myAction.bind(null, dispatch) 
    }; 
} 


export default function(component = Component) { 
    return connect(mapStateToProps, mapDispatchToProps)(component); 
} 

你會注意到在mapStateToProps的normalizedState,我用這個搶我想在這個容器使用狀態的部分,除非你的應用程序只有1個智能組件,那麼你可能不會這樣做。它只是抓住了我在這個容器中使用的狀態(來自不可變)的部分,在你的情況下它是pushMessages。所以現在在你連接的這個組件中,你應該有this.props.messages與你的物品。我還使用mapDispatchToProps來綁定我的動作,因爲它可以讓您在動作創作者中進行分派,這使得異步非常容易。

隨着組合代碼正確連接起來(我不知道在這裏連接動作),您應該在action.PushMessage上觸發RECEIVED_PUSH_MESSAGE動作創建器併發送新消息。然後,這會連接到您的mapStateToProps,它將更新組件上的this.props.messages,該組件只應呈現列表中的最後一項。

+0

這非常有幫助!非常感謝!只有一件事是使用你提供的代碼,它似乎並沒有將PushMessage添加到列表中。它創建地圖並將狀態視爲地圖,但地圖始終爲空。再次感謝! – LivingRobot

+0

@ user5407287我真的不明白你在這裏說什麼。狀態是一個對象,但在狀態內創建的消息部分是一個列表。如果將此連接正確連接到您的redux商店並聲明您將具有如上所列的設置狀態。只要記住這是有點僞代碼和即時通訊使用不可變,但它應該工作。你可能想展示你如何連接REDX和容器。比如你如何做mapStateToProps的例子? – ajmajmajma

+0

我編輯了包含更多代碼。再次感謝你的幫助。 – LivingRobot