2016-11-15 68 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.