12

我正在将 React 与 Redux 和 Material UI 一起使用来构建 web 应用程序。webapp 由多个页面和组件组成。我知道快餐栏或对话框应该直接连接到用户正在做的事情。但是,我想让快餐栏和对话框独立于页面和组件。因此,一个用例正在显示一条消息 likebackground synchronization of your data failed和一个 action retry now。我的想法是在一个名为 的页面上呈现snackbar,该页面RootFrame用于包装所有其他页面并将snackbar 的文本作为操作的有效负载发送。

我的 Redux 操作来显示一个小吃吧:

export function showSnackbar(message: string) {
  return {
    type: SHOW_SNACKBAR,
    payload: message
  };
}

当然,在操作中指定消息而不是将消息作为参数也可能会很好,但这不是我现在的问题。问题是:我怎样才能使用这个系统并显示一个带有动作的snackbar?我可以将我的操作更改为

export function showSnackbar(message, action) {
  return {
    type: SHOW_SNACKBAR,
    payload: {
      message, 
      action
    }
  };
}

RootFrame并以类似的方式渲染我的小吃店

<Snackbar
  message={this.props.message}
  ref='snackbar'
  onDismiss={() => this.props.dispatch(dismissSnackbar())}
  action='retry now'
  onActionTouchTap={() => this.props.dispatch(this.props.action)}
/>;

当快餐栏被关闭时,一个动作会改变状态中的一个变量:snackbar.visible = false。这用于激活快餐栏(它在 时呈现snackbar.visible === true)。当用户点击 时retry now,启动同步的动作(作为道具传递给组件)应该被调度。使用对话框时问题非常相似。因此,不仅要显示的文本,而且下一个可能的操作都必须传递给组件。

你认为像这样使用 Redux 是可以的还是有更好的解决方案?

4

1 回答 1

5

实际上,现在 usign redux 做了一点改动。我们使用createActionfrom redux-act,正确地使用createReducer更多。在组件中,我们使用 connect 装饰器或来自react-redux. 连接器提供 redux 状态、调度的动作、父道具。所以对于我们的小吃店,我们有:

  1. 行动:

    export const showMessageTop = createAction();
    export const closeMessageTop = createAction();
    
  2. 减速器:

    import {createReducer} from 'redux-act';
    import * as ac from '../actionCreators/messageTop';
    export default createReducer(
      {
        [ac.showMessageTop]: (state, messageText) => ({messageText}),
        [ac.closeMessageTop]: () => ({messageText: ''}),
      },
      {
        messageText: window.location.search === '?login=1'
                   ? 'Welcome'
                   : '',
      }
    )
    
  3. 和一个组件(使用装饰器而不是类):

    import {closeMessageTop} from '../../actionCreators/messageTop'; 
    import MessageTop from './MessageTop';
    @connect(state => ({
      // gettext: gettext(state.locale.messages),
      messageText: state.messageTop.messageText,
    }))
    export default class MessageTopContainer extends React.Component {
    ...
    <button onClick={...bindActionCreators({onClose: closeMessageTop}, dispatch)}/>
    

所以在当前的道具中,我们有this.props.messageText. 如果我们有消息,我们可以显示这个栏,或者我们可以调用空字符串中的closeAction设置messageText

于 2015-11-04T08:04:10.357 回答