Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Implemented the ApolloConsumer component. #1399

Merged
merged 6 commits into from
Dec 26, 2017

Conversation

excitement-engineer
Copy link
Contributor

@excitement-engineer excitement-engineer commented Dec 10, 2017

The roadmap for v2.1 describes moving to a component based API (Query, Mutation and Subscription) in addition to the HOCs.

I implemented the component associated with the existing HOC withApollo called ApolloConsumer. This will allow users access to the apollo-client instance using a render prop as follows:

<ApolloConsumer render={client => {
    return <div>data</div>
}} />

I got my inspiration from react-router's API. They have a Route component and a withRouter HOC. The implementation of the HOC is simply a wrapper around the Route component. The same could be done for withApollo, it can simply wrap the ApolloConsumer.

Curious to hear how people feel about such a component and the API proposed above.

Note, this is a WIP. Tests still need to be added.

@rosskevin
Copy link
Contributor

Style-wise you could use children as the render call back, no need to add a render prop. Adding a render prop is more verbose but achieves the same thing. react-i18next is a good example of this.

@apollo-cla
Copy link

apollo-cla commented Dec 15, 2017

Warnings
⚠️

There are library changes, but not tests. That's OK as long as you're refactoring existing code

Generated by 🚫 dangerJS

@excitement-engineer
Copy link
Contributor Author

Hey @rosskevin, this is indeed a style issue. I know that react router uses the "render" prop pattern for example. I will leave it the way it is for now and wait for feedback from others:)

@excitement-engineer
Copy link
Contributor Author

I updated the component to use children for rendering in favor of a render prop.

Copy link
Contributor

@rosskevin rosskevin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just one thing on the return type.

const invariant = require('invariant');

export interface ApolloConsumerProps {
children: (client: ApolloClient<any>) => React.ReactElement<any>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the return should React.ReactNode - it is looser than ReactElement and we have no real concerns about the return type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, as soon as I update the type to React.ReactNode I get the typescript error:

Type '(props: ApolloConsumerProps & { children?: ReactNode; }, context: any) => ReactNode' is not assignable to type 'StatelessComponent<ApolloConsumerProps>'.
  Type 'ReactNode' is not assignable to type 'ReactElement<any>'.
    Type 'string' is not assignable to type 'ReactElement<any>'.

It seems that StatelessComponent not accept a ReactNode as the return type. Any ideas on how to fix this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's mistake then, it should match render's return type. I was thinking it would be node because 16 allows arrays.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should say my mistake - I'm mobile

@rosskevin rosskevin merged commit 1ae46f1 into apollographql:master Dec 26, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants