清除Redux商店

时间:2016-08-01 18:32:14

标签: reactjs redux react-redux

我有一个Web套接字,它接受一个名为PushMessage的对象,并将其发送到React页面,该页面随后会实时更新。这种方式的工作方式是用户搜索他希望显示的PushMessage,然后将其传入。但是,现在发生的情况是,如果用户搜索第一个PushMessage,则显示该那个,但是如果他或者然后,她搜索另一个PushMessage,并显示它们。我想只显示其中的第二个。为了做到这一点,我觉得我需要清除Redux存储(将其恢复到初始的空状态)。但是,我无法弄清楚如何做到这一点。

我的减速机由:

给出
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 个答案:

答案 0 :(得分:2)

你可以通过多种方式实现这一目标,我将告诉你如何接近它。让我们立刻看看你的状态 - 因为你正在使用联合减速器,你就像这样分裂你的状态:

{
  pushMessages: { pushMessages state in here }
}

因此,当你想将你的应用程序拆分成某种“子状态”时,combineReducers非常棒,在这种情况下,redux仍然是单一商店。现在你只有pushMessages的单个子状态。

我会接受组件并设置一个操作来向其添加消息(最终可能会删除一条消息)。我正在使用immutable.js,因为我碰巧喜欢使用它和IMO它使得redux很好用,因为状态应该是不可变的(再次,个人意见)。

所以这是你的减速器:

 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动作而且只是从该数组消息中弹出或拼接。 (然后你可以在没有_.last的情况下显示this.props.message)。希望这有帮助!

编辑:

以下是我设置容器的方法:

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绑定我的动作,因为它可以让你在你的动作创建者中进行调度,这使异步变得非常容易。

如果合并的代码已正确连接(我不知道在此处挂钩操作),您应该在RECEIVED_PUSH_MESSAGE上使用新消息触发action.PushMessage动作创建者。然后连接到mapStateToProps,它会更新组件上的this.props.messages,这只应该呈现列表中的最后一项。