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

React createContext wrapper #19

Closed
garrett-hopper opened this issue Feb 13, 2019 · 8 comments
Closed

React createContext wrapper #19

garrett-hopper opened this issue Feb 13, 2019 · 8 comments
Labels
enhancement New feature or request good first issue Good for newcomers

Comments

@garrett-hopper
Copy link

Are there any plans to add wrappers for things such as createContext (similar to the dummy wrappers in hx.hooks such as <-reducer)?

It would be nice to do some Clojure wrapping to for easily getting out the Consumer and Provider by key.

@lilactown
Copy link
Collaborator

I don't see why not - PRs welcome! I might get around to this during the weekend.

In the meantime I'm going to try and clean up the code so that it's easier for others to jump into 😅

@lilactown lilactown added enhancement New feature or request good first issue Good for newcomers labels Feb 13, 2019
@dawranliou
Copy link
Contributor

dawranliou commented Feb 16, 2019

Hey I'd like to help with this. Any feedback would be helpful because I'm not very familiar with createContext.

I'm thinking about adding the wrapper function that returns a map containing the producer and consumer:

(defn context
  "Use react/createContext and return a map of Producer and Consumer."
  [value]
  (let [context (react/createContext value)]
    {:provider (.-Provider context)
     :consumer (.-Consumer context)}))

However, I'm not sure how to test this function. Would you give me some suggestion? Thank you!

@dawranliou
Copy link
Contributor

I just found the function hx.hooks/<-context. It'd be better if the output of the above context function can be passed into <-context too. I'm thinking of making <-context to a multimethod to handle both the map scenario and the React.Context object scenario. What's your thought on this solution?

@lilactown
Copy link
Collaborator

lilactown commented Feb 16, 2019

Hmm good point about <-context. Perhaps a differect tactic is in order.

One thing to note is that most libraries expose Provider and Consumer components separately, rather than exposing the raw Context value returned by createContext.

So the case we're talking about is most useful when we're using a Context value we've created ourselves.

Another option: we could add a new hiccup element, :provider, that would allow you to pass in a Context value and it would create the Provider for you.

Example:

(def my-context (react/createContext))

(defnc Child [_]
  (let [value (<-consume my-context)]
    [:div value]))

(defnc App [_]
  [:provide {:context my-context
             :value "something"}
   [Child]])

I can think of other ways, like trying to get crafty with protocols or whatnot, but probably not worth the effort.

@dawranliou
Copy link
Contributor

Thanks for responding @Lokeh !

One thing to note is that most libraries expose Provider and Consumer components separately, rather than exposing the raw Context value returned by createContext.
So the case we're talking about is most useful when we're using a Context value we've created ourselves.

I'm not sure if I understand you correctly. Do you have an example that exposes Provider and Consumer separately? I'm just not sure which would be more valuable/desirable: a) expose raw Context, or b) expose Provider and Consumer, or c) all of them. (Sorry I don't have much experience with the context object.)

I like your example above. It feels a lot like what I'd rather write in clojure instead of thinking the raw js objects. Do you think this is a separate PR?

@lilactown
Copy link
Collaborator

Sure, an example would be the way the Emotion CSS library does theming: https://github.com/emotion-js/emotion/blob/master/docs/theming.md

They expose a ThemeProvider component that you pass in the current theme to. You then can access theme theme prop in any styled components or using a withTheme higher-order component.

In this case we don't need to do anything fancy, we can just use the ThemeProvider and withTheme HOC as usual.

The annoying bit is when, in CLJS, we want to create and use context. Right now, you have to use JS interop to get at the Provider component.

This isn't super heinous to me but I see why people might not like it. So I think that to aid with this, we should have a :provider component that you pass in the context value created by react/createContext and it will pull the provider out for you.

We could also have a hx.react/create-context function that just proxies react/createContext since requiring React just for creating context is a bit annoying.

At the end of the day this is all small QoL enhancements so not super high on my list. But PRs welcome!

@dawranliou
Copy link
Contributor

Thanks, I see how this is useful now. I would love to work on the PR for this. Thanks for taking the time explaining.

@lilactown
Copy link
Collaborator

Closing this with #25 merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers
Projects
None yet
Development

No branches or pull requests

3 participants