Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion] Provide configuration through Context API #26

Open
ecwyne opened this issue Aug 12, 2020 · 6 comments
Open

[Discussion] Provide configuration through Context API #26

ecwyne opened this issue Aug 12, 2020 · 6 comments

Comments

@ecwyne
Copy link

ecwyne commented Aug 12, 2020

Instead of providing a Client instance to each hook, it would be much cleaner and more intuitive to provide client parameters through context.

Prior art:
vercel/swr
@apollo/client
tannerlinsley/react-query

@ryancharris
Copy link
Owner

@ecwyne Thanks for the note 👍 I've actually been thinking about that as well. When I refactored useDatabase to be useFaunaClient I was considering changing the former to provide some Context values to use throughout the app. I'll certainly take a look at the references you provided me.

My think is if we instantiate a Client with useFaunaClient we can pipe it to the sub-tree with a Context provider for components that care. This way, we could also use different clients for different parts of the app if we don't want all the data living in one DB.

What do you think?

@ecwyne
Copy link
Author

ecwyne commented Aug 14, 2020

I definitely think it's possible to make it so that you can pass different client parameters to different sub-trees and merge them with the configurations from parent providers.

Eg.

<FaunaProvider config={{ secret: 'secret1' }}>
    <ComponentOne />
    <FaunaProvider config={{ secret: 'secret2' }}>
        <ComponentTwo />
    </FaunaProvider>
    <FaunaProvider  config={{ observer: console.log }}>
        <ComponentThree />
    </FaunaProvider>
</FaunaProvider>

@ecwyne
Copy link
Author

ecwyne commented Aug 14, 2020

I would suggest having a useFaunaClient hook that uses the configuration options provided in context to create the Client instance. It would not be possible to merge configurations if you're passing down the Client instance itself

const useFaunaClient = () => {
    const { config } = useContext(FaunaContext);
    return new Client(config);
};

@ryancharris
Copy link
Owner

I definitely think it's possible to make it so that you can pass different client parameters to different sub-trees and merge them with the configurations from parent providers.

Eg.

<FaunaProvider config={{ secret: 'secret1' }}>
    <ComponentOne />
    <FaunaProvider config={{ secret: 'secret2' }}>
        <ComponentTwo />
    </FaunaProvider>
    <FaunaProvider  config={{ observer: console.log }}>
        <ComponentThree />
    </FaunaProvider>
</FaunaProvider>

Awesome. I was definitely thinking something along these lines 🙌 I can imagine folks wanting to isolate data from different parts of their app in different DBs, which they can provide to pages/components through a Context.Provider.

@ryancharris
Copy link
Owner

I would suggest having a useFaunaClient hook that uses the configuration options provided in context to create the Client instance. It would not be possible to merge configurations if you're passing down the Client instance itself

const useFaunaClient = () => {
    const { config } = useContext(FaunaContext);
    return new Client(config);
};

Originally, I was thinking useFaunaClient would work as it does now and that you'd then pass it into a useDatabase hook. That hook would return a Context and a Context provider with the Client instance as its value.

Something like this:

// App.js
const client = useFaunaClient(KEY)
const [DatabaseProvider] = useDatabase(client)

return (
  <DatabaseProvider>
    <Component1 />
    <Component2 />
  </DatabaseProvider>
)

// Component2
const client = useFaunaClient(KEY)
const [DataContext] = useDatabase(client)
const data = useContext(DataContext)

What do you think? Certainly not married to this implementation 😅

@ecwyne
Copy link
Author

ecwyne commented Aug 14, 2020

As written useFaunaClient requires you to keep track of a secret throughout your app and pass it every time.

I believe useFaunaClient shouldn't take any arguments at all and returns a client based on the context it's being run in. This is how useApolloClient works

Also, I'm not sure what you mean by Database. (In your example useDatabase() returns either a [DatabaseProvider] or [DataContext]?

In practice, I almost never think about the Fauna idea of a Database. I use a client to read Documents from Collections, match Indexes, and call Functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants