2017-08-20 17 views
0

在閱讀post之後,有關向一個graphql注入的對象添加流類型是多麼容易,我認爲我會試一試。由於6月份的這篇文章已經升級到0.53,我無法獲得使用類組件的基本示例。我不確定這是否是react-apollo的原始定義中的升級或其他問題。在應用apollo的graphql()後缺少數據通道導致的流程類型錯誤HOC

問題:如何讓組件的類版本工作?

這裏是我的示例代碼:

// @flow 
import * as React from 'react'; 
import gql from 'graphql-tag'; 
import { graphql } from 'react-apollo'; 
import type { OperationComponent, QueryOpts } from 'react-apollo'; 

const HERO_QUERY = gql` 
    query GetCharacter($episode: Episode!) { 
    hero(episode: $episode) { 
     name 
     id 
     friends { 
     name 
     id 
     appearsIn 
     } 
    } 
    } 
`; 
type Hero = { 
    name: string, 
    id: string, 
    appearsIn: string[], 
    friends: Hero[] 
}; 
type Response = { 
    hero: Hero 
}; 

type Props = { 
    data: QueryOpts & Response, 
} 

const withCharacter: OperationComponent<Response, Props> = graphql(HERO_QUERY, { 
    options:() => ({ 
    variables: { episode: 'JEDI' }, 
    }), 
}); 

class TestClass extends React.Component<Props> { 
    render() { 
    const { loading, error, hero } = this.props.data; 
    if (loading) return <div>Loading</div>; 
    if (error) return <h1>ERROR</h1>; 
    return <div>My hero: {hero.name}</div>; 
    } 
} 

const TestFn = ({ data: { loading, error, hero } }) => { 
    if (loading) return <div>Loading</div>; 
    if (error) return <h1>ERROR</h1>; 
    return <div>My hero: {hero.name}</div>; 
}; 

export const clss = withCharacter(TestClass); // ERROR! 
export const fn = withCharacter(TestFn); // Works fine 

這裏是FR的OperationComponent類型的定義,它的核心部件從definition與更新相匹配的0.53流量風格:

export interface QueryProps { 
    error?: ApolloError, 
    networkStatus: number, 
    loading: boolean, 
    variables: Object, 
    fetchMore: (
    fetchMoreOptions: FetchMoreQueryOptions & FetchMoreOptions, 
) => Promise<ApolloQueryResult<any>>, 
    refetch: (variables?: Object) => Promise<ApolloQueryResult<any>>, 
    startPolling: (pollInterval: number) => void, 
    stopPolling:() => void, 
    subscribeToMore: (options: SubscribeToMoreOptions) =>() => void, 
    updateQuery: (
    mapFn: (previousQueryResult: any, options: UpdateQueryOptions) => any, 
) => void, 
} 

export type MutationFunc<TResult> = (
    opts: MutationOpts, 
) => Promise<ApolloQueryResult<TResult>>; 

export type ChildProps<P, R> = { 
    data: QueryProps & R, 
    mutate: MutationFunc<R>, 
} & P; 

export interface OperationComponent< 
    TResult: Object = {}, 
    TOwnProps: Object = {}, 
    TMergedProps = ChildProps<TOwnProps, TResult>, 
> { 
    (
    component: 
     | StatelessComponent<TMergedProps> 
     | Class<React$Component<any, TMergedProps, any>>, 
): Class<React$Component<TOwnProps, void>>, 
} 

declare export function graphql<TResult, TProps, TChildProps>(
    document: DocumentNode, 
    operationOptions?: OperationOption<TProps, TResult>, 
): OperationComponent<TResult, TProps, TChildProps>; 

當我運行flow focus-check src/test.js(v。0.53.1)我得到:

Error: src/test.js:42 
42:  const { loading, error, hero } = this.props.data; 
       ^^^^^^^ property `loading`. Property cannot be accessed on any member of intersection type 
42:  const { loading, error, hero } = this.props.data; 
              ^^^^^^^^^^^^^^^ intersection 
    Member 1: 
    31: data: QueryOpts & Response, 
       ^^^^^^^^^ QueryOpts 
    Error: 
    42:  const { loading, error, hero } = this.props.data; 
        ^^^^^^^ property `loading`. Property not found in 
    31: data: QueryOpts & Response, 
       ^^^^^^^^^ QueryOpts 
    Member 2: 
    31: data: QueryOpts & Response, 
          ^^^^^^^^ Response 
    Error: 
    42:  const { loading, error, hero } = this.props.data; 
        ^^^^^^^ property `loading`. Property not found in 
    31: data: QueryOpts & Response, 
          ^^^^^^^^ object type 

Error: src/test.js:42 
42:  const { loading, error, hero } = this.props.data; 
          ^^^^^ property `error`. Property cannot be accessed on any member of intersection type 
42:  const { loading, error, hero } = this.props.data; 
              ^^^^^^^^^^^^^^^ intersection 
    Member 1: 
    31: data: QueryOpts & Response, 
       ^^^^^^^^^ QueryOpts 
    Error: 
    42:  const { loading, error, hero } = this.props.data; 
          ^^^^^ property `error`. Property not found in 
    31: data: QueryOpts & Response, 
       ^^^^^^^^^ QueryOpts 
    Member 2: 
    31: data: QueryOpts & Response, 
          ^^^^^^^^ Response 
    Error: 
    42:  const { loading, error, hero } = this.props.data; 
          ^^^^^ property `error`. Property not found in 
    31: data: QueryOpts & Response, 
          ^^^^^^^^ object type 

Error: src/test.js:55 
55: export const clss = withCharacter(TestClass); 
             ^^^^^^^^^ class type: TestClass. This type is incompatible with 
      v------------------------------- 
123:  | StatelessComponent<TMergedProps> 
124:  | Class<React$Component<any, TMergedProps, any>>, 
      -----------------------------------------------^ union: type application of polymorphic type: type `StatelessComponent` | class type: type application of identifier `React$Component`. See: node_modules/react-apollo/react-apollo.umd.js.flow:123 
    Member 1: 
    123:  | StatelessComponent<TMergedProps> 
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type application of polymorphic type: type `StatelessComponent`. See: node_modules/react-apollo/react-apollo.umd.js.flow:123 
    Error: 
    123:  | StatelessComponent<TMergedProps> 
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function type. Callable signature not found in. See: node_modules/react-apollo/react-apollo.umd.js.flow:123 
    55: export const clss = withCharacter(TestClass); 
             ^^^^^^^^^ statics of TestClass 
    Member 2: 
    124:  | Class<React$Component<any, TMergedProps, any>>, 
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ class type: type application of identifier `React$Component`. See: node_modules/react-apollo/react-apollo.umd.js.flow:124 
    Error: 
    124:  | Class<React$Component<any, TMergedProps, any>>, 
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type application of identifier `React$Component`. Too many type arguments. Expected at most 2. See: node_modules/react-apollo/react-apollo.umd.js.flow:124 
    29: declare class React$Component<Props, State = void> { 
            ^^^^^^^^^^^^ See type parameters of definition here. See lib: /tmp/flow/flowlib_1135e841/react.js:29 


Found 3 errors 

我試着加入一些改進0.53,但沒有無濟於事:

export interface OperationComponent< 
    TResult: Object = {}, 
    TOwnProps: Object = {}, 
    TMergedProps = ChildProps<TOwnProps, TResult>, 
> { 
    (
    component: React$ComponentType<TMergedProps> 
): React$ComponentType<TOwnProps>, 
} 

回答

1

哦...不對查詢,應該是QueryProps而不是QueryOpts

// @flow 
import * as React from 'react'; 
import gql from 'graphql-tag'; 
import { graphql } from 'react-apollo'; 
import type { OperationComponent, QueryProps } from 'react-apollo'; 

const HERO_QUERY = gql` 
    query GetCharacter($episode: Episode!) { 
    hero(episode: $episode) { 
     name 
     id 
     friends { 
     name 
     id 
     appearsIn 
     } 
    } 
    } 
`; 

type Hero = { 
    name: string, 
    id: string, 
    appearsIn: string[], 
    friends: Hero[] 
}; 

type Response = { 
    hero: Hero 
}; 

type Props = { 
    data: QueryProps & Response, 
    mutate: any, 
} 

const withCharacter: OperationComponent<Response, Props> = graphql(HERO_QUERY, { 
    options:() => ({ 
    variables: { episode: 'JEDI' }, 
    }), 
}); 

class TestClass extends React.Component<Props> { 
    render() { 
    const { loading, error, hero } = this.props.data; 
    if (loading) return <div>Loading</div>; 
    if (error) return <h1>ERROR</h1>; 
    return <div>My hero: {hero.name}</div>; 
    } 
} 

const TestFn = ({ data: { loading, error, hero } }) => { 
    if (loading) return <div>Loading</div>; 
    if (error) return <h1>ERROR</h1>; 
    return <div>My hero: {hero.name}</div>; 
}; 

export const clss = withCharacter(TestClass); // Works 
export const fn = withCharacter(TestFn); // Works