12

React と Redux および Material UI を使用して webapp を構築しています。Web アプリケーションは、いくつかのページとコンポーネントで構成されています。スナックバーまたはダイアログは、ユーザーが行っていることに直接接続する必要があることを知っています。ただし、ページとコンポーネントでスナックバーとダイアログを独立させたいと考えています。したがって、ユースケースは、のようなメッセージbackground synchronization of your data failedとアクションを表示していますretry now。私のアイデアは、スナックバーを というページにレンダリングすることでしたRootFrame。これは、他のすべてのページをラップし、アクションのペイロードとしてスナックバーのテキストをディスパッチするために使用されます。

スナックバーを表示する私の Redux アクション:

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

もちろん、メッセージを引数として受け取る代わりに、アクションでメッセージを指定することも良いかもしれませんが、それは今のところ私の問題ではありません。問題は、このシステムを使用してアクション付きのスナックバーを表示するにはどうすればよいかということです。自分の行動を次のように変更できますか

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)}
/>;

スナックバーが閉じられると、アクションによって state: の変数が変更されますsnackbar.visible = false。これは、スナックバーを有効にするために使用されます ( の場合にレンダリングされますsnackbar.visible === true)。ユーザーが をクリックするとretry now、同期を開始するアクション (props としてコンポーネントに渡される) がディスパッチされる必要があります。ダイアログを使用する場合、問題は非常に似ています。したがって、表示するテキストだけでなく、次の可能なアクションもコンポーネントに渡す必要があります。

このように Redux を使用しても問題ないと思いますか、それともより良い解決策はありますか?

4

1 に答える 1

5

実は現在、usign redux が少し変更されています。から使用createActionredux-act、適切にcreateReducerさらに使用します。コンポーネントでは、connect デコレータまたは class from を使用しreact-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 に答える