2016-11-15 6 views
7

방금 ​​flowtype을 배우기 시작했고 마음에 분명하지 않은 두 가지 사항을 이해하기 위해 도움이 필요합니다.flowtype을 사용하여 비동기 액션 제작자를 바인딩하는 방법은 무엇입니까?

  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는 포장한다 012613671284292641172076에있는 profileActionCreators의 각 속성. 디스패치가 나중에 콜백으로 사용될 수있는 setProfile 함수에 전달 될 것으로 예상하는 것 같습니다.

그러나 bindActionCreators가 "바인딩"디스패치를 ​​콜백으로 지원하지 않는다고 생각합니다. 오히려, 파견이 같은 "바인딩"되어

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

Flowtype 따라서 제대로 bindActionCreators 각 속성을 기대하는 말, 유형 오류 잡기 : 코드에서 그래서

function bindActionCreator(actionCreator, dispatch) { 
    return (...args) => dispatch(actionCreator(...args)) 
} 

, 그것은 효과적으로 다음과 같습니다 actionCreator : () => Action이 될 개체의 이름입니다.

사용 사례에 bindActionCreators를 사용할 수 없거나 썽크를 처리하는 방법을 다시 생각해 봐야합니다. 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.