2016-11-15 41 views
7

我剛開始學習流式,我需要一些幫助來理解兩件事情,這些事情在我的腦海中並不清楚。如何使用流式綁定異步操作創建者?

  1. 使用https://github.com/reactjs/redux/blob/master/examples/todos-flow作爲一個例子,我不知道如何通過類型的控制也能沒有https://github.com/flowtype/flow-typed類型定義的工作,在這種情況下:https://github.com/flowtype/flow-typed/blob/master/definitions/npm/redux_v3.x.x/flow_v0.33.x-/redux_v3.x.x.js

  2. 如果我使用redux定義,bindActionCreators的驗證失敗,當我嘗試綁定異步操作創建者(我使用的是redux-thunk)。

如何在使用redux-thunk時繼續使用流和綁定異步動作創建器?

代碼示例(https://gist.github.com/momsse/323c228e8c5e264067039b8446cd890f):

import { bindActionCreators } from 'redux'; 
import type { Dispatch } from 'redux'; 

type Action = { type: 'SET_PROFILE', profile: Object }; 

/** 
* Based on https://github.com/gaearon/redux-thunk/blob/master/index.d.ts 
*/ 
type ThunkAction = (dispatch: Dispatch<Action>, 
        getState:() => any, 
        extraArgument: any) => any; 

type Profile = { 
    name: string, 
    team: string 
} 

// Async actions creator 
function setProfile(profile: Profile): ThunkAction { 
    return dispatch => setTimeout(() => dispatch({ type: 'SET_PROFILE', profile }), 2000); 
} 

const profileActionCreators = { setProfile }; 

type Props = { 
    actions: { 
    setProfile: (profile: Profile) => ThunkAction, 
    } 
} 

function mapDispatchToProps(dispatch: Dispatch<Action>): Props { 
    return { 
    actions: bindActionCreators(profileActionCreators, dispatch) 
    }; 
} 

錯誤:

40:  actions: bindActionCreators(profileActionCreators, dispatch) 
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call. Function cannot be called on any member of intersection type 
40:  actions: bindActionCreators(profileActionCreators, dispatch) 
        ^^^^^^^^^^^^^^^^^^ intersection 
    Member 1: 
    49: declare function bindActionCreators<A, C: ActionCreator<A, any>>(actionCreator: C, dispatch: Dispatch<A>): C; 
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ polymorphic type: function type. See lib: flow-typed/npm/redux_v3.x.x.js:49 
    Error: 
    49: declare function bindActionCreators<A, C: ActionCreator<A, any>>(actionCreator: C, dispatch: Dispatch<A>): C; 
                ^^^^^^^^^^^^^^^^^^^^^ function type. Callable signature not found in. See lib: flow-typed/npm/redux_v3.x.x.js:49 
    40:  actions: bindActionCreators(profileActionCreators, dispatch) 
             ^^^^^^^^^^^^^^^^^^^^^ object literal 
    Member 2: 
    50: declare function bindActionCreators<A, K, C: ActionCreators<K, A>>(actionCreators: C, dispatch: Dispatch<A>): C; 
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ polymorphic type: function type. See lib: flow-typed/npm/redux_v3.x.x.js:50 
    Error: 
    13: declare type Dispatch<A: { type: $Subtype<string> }> = (action: A) => A; 
            ^^^^^^^^^^^^^^^^^^^^^^^^^^ property `type` of object type. Property not found in. See lib: flow-typed/npm/redux_v3.x.x.js:13 
    21: function setProfile(profile: Profile): ThunkAction { 
               ^^^^^^^^^^^ function type 

回答

0

這些是ActionCreator完整的聲明和bindActionCreators:

declare type ActionCreator<A, B> = (...args: Array<B>) => A; 
    declare type ActionCreators<K, A> = { [key: K]: ActionCreator<A, any> }; 

    declare function bindActionCreators<A, C: ActionCreator<A, any>>(actionCreator: C, dispatch: Dispatch<A>): C; 
    declare function bindActionCreators<A, K, C: ActionCreators<K, A>>(actionCreators: C, dispatch: Dispatch<A>): C; 

在你的代碼,bindActionCreators將包裹profileActionCreators的每個屬性dispatch。您似乎希望將dispatch傳遞給setProfile函數,在此函數中稍後可以將dispatch用作回調函數。

但在我看來,bindActionCreators支持「綁定」調度作爲回調。相反,派遣「綁定」是這樣的:

function bindActionCreator(actionCreator, dispatch) { 
    return (...args) => dispatch(actionCreator(...args)) 
} 
在你的代碼

因此,它有效地看起來是這樣的:因此

function mapDispatchToProps(dispatch: Dispatch<Action>): Props { 
    return { 
    actions: { 
     setProfile: (profile) => dispatch(dispatch => setTimeout(() => dispatch({ type: 'SET_PROFILE', profile }), 2000)), 
    }; 
} 

流動型是否正確捕捉類型的錯誤,說bindActionCreators預計每個屬性該對象是一個actionCreator:() => Action

您可能無法爲您的用例使用bindActionCreators,或者您需要重新考慮如何處理thunk。 Here is an approach that should work

const profileActionCreators = { setProfile }; 

type Props = { 
    actions: { 
    setProfile: (profile: Profile) => setTimeout, 
    } 
} 

function mapDispatchToProps(dispatch: Dispatch<Action>): Props { 
    const boundActions = bindActionCreators(
    profileActionCreators, 
    dispatch 
); 
    return ({ 
    actions: { 
     setProfile: (profile: Profile) => setTimeout(() => boundActions.setProfile(profile), 2000), 
    }, 
    }); 
} 

咚方法

如果你想讓你的ThunkAction方法,你將無法使用bindActionCreators。 This also works.