2017-09-05 3 views
1

私は、React、Redux、TypeScriptを一緒に使用するときの定型文の量を減らす方法を理解しようとしています。この場合はあなたができないかもしれないが、誰かがアイディアを持っているかどうかを見たいと思っていたかもしれません。React、Redux、およびTypeScriptを使用したmapDispatchToPropsの短縮方法はありますか?

私は現在、メニューの表示と非表示を交互に切り替えるアクションをディスパッチするコンポーネントを持っています。アクションはそれはそれのように感じている

export function toggleMenu(isActive: boolean): Dispatch<Action> { 
    return (dispatch: Dispatch<Action>) => { 
    dispatch({ 
     isActive, 
     type: "TOGGLE_MENU", 
    }); 
    }; 
} 

として定義されて

import {Action, toggleMenu} from "../../actions/index";  

interface IConnectedDispatch { 
    toggleMenu: (isActive: boolean) => Action; 
} 

class HeaderMenu extends React.Component<IOwnProps & IConnectedState & IConnectedDispatch, any> { 

    constructor(props: IOwnProps & IConnectedState & IConnectedDispatch) { 
    super(props); 
    this.toggleMenuState = this.toggleMenuState.bind(this); 
    } 

    public render() {   
    return (
     <button className={buttonClass} onClick={this.props.toggleMenu(this.props.isActive)} type="button"> 
     </button> 
    ); 
    } 
} 

const mapDispatchToProps = (dispatch: redux.Dispatch<Store.All>): IConnectedDispatch => ({ 
    toggleMenu: (isActive: boolean) => dispatch(toggleMenu(isActive))}); 

:これを行うには、私は私のクラスのようなもの(状態に関係省いコード、アクションのディスパッチに焦点を当てた)を定義しましたここで私の目標を達成するのに必要なコードの量を減らすことができるはずです。 React、Redux、TypeScriptの新機能であるが、私は正確にどのように見えているのか分からない。具体的には、アクション名toggleMenuを繰り返し記述することは非常に反復的です。たとえば、この部分の2回:

const mapDispatchToProps = (dispatch: redux.Dispatch<Store.All>): IConnectedDispatch => ({ 
    toggleMenu: (isActive: boolean) => dispatch(toggleMenu(isActive))}); 

何かアドバイスありがとうございます。

答えて

4

短い方法があります。多くのコードを単純化することができます。

アクション - オリジナル

export function toggleMenu(isActive: boolean): Dispatch<Action> { 
    return (dispatch: Dispatch<Action>) => { 
    dispatch({ 
     isActive, 
     type: "TOGGLE_MENU", 
    }); 
    }; 
} 

アクション - 削減

export const toggleMenu = (isActive: boolean) => ({ 
    isActive, 
    type: "TOGGLE_MENU" 
}) 

プロパティインタフェース -

import { toggleMenu } from "./actions" 
interface IConnectedDispatch { 
    toggleMenu: typeof toggleMenu 
} 
削減 - オリジナル

interface IConnectedDispatch { 
    toggleMenu: (isActive: boolean) => Action; 
} 

プロパティインタフェース

MapDispatch - 私はこのライブラリtypescript-fsaをお勧めすることができます

const mapDispatchToProps = { 
    toggleMenu 
}; 

を削減 - オリジナル

const mapDispatchToProps = (dispatch: redux.Dispatch<Store.All>): IConnectedDispatch => ({ 
    toggleMenu: (isActive: boolean) => dispatch(toggleMenu(isActive))}); 

MapDispatch。これは、アクション、特に非同期アクションによって作成された多くの定型文を減らすのに役立ちます。

+0

素晴らしい!ありがとう@ニバ! – langkilde

+0

@nibaこれにはどのように 'connect'を呼びますか? 'mapDispatchToProps'を' const mapDispatchToProps =(dispatch):IConnectedDispatch => {toggleMenu} 'と宣言しない限り、' connect'はタイプを正しく推論しません。 'export default ReactRedux.connect(mapStateToProps、mapDispatchToProps)(HeaderMenu);' ... – mikebridge

+0

私は標準の 'connect'を使っていません。私は後で私のコンテナ定義に入れることができる 'mapStateToProps'と' mapDispatchToProps'から型を自動的に取り出す 'connect'の周りに私の特別なラッパーを持っています。とにかく、私は 'connect(state => state、{... actions})(Component); 'を実行しようとしましたが、問題はありません。あなたの接続はどんなタイプで正しく推論されませんか? – niba

2

mapDispatchToPropsは、機能の代わりにアクションクリエイターのオブジェクトを受け入れ、それらをすべて自動的にdispatchにバインドします。

From the docs

オブジェクトが渡された場合、その内部の各機能は、Reduxのアクションの作成者であると仮定されます。

const mapDispatchToProps = { 
    toggleMenu 
}; 
:同じ関数名を持つオブジェクトが、彼らは直接起動することができるよう dispatchコールに包まれたすべてのアクションの作成者には、これはあなたのようにそれを書き換えることを可能にするコンポーネントの小道具

にマージされます

注:これをタイプ文字で(もしあれば)入力する必要があるか分かりません。

関連する問題