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

Context API support #50

Open
kball opened this issue Jul 30, 2018 · 13 comments
Open

Context API support #50

kball opened this issue Jul 30, 2018 · 13 comments

Comments

@kball
Copy link

kball commented Jul 30, 2018

I'm attempting to utilize Vuera to create Gutenberg components for Wordpress using Vue. Overall I'm pretty happy with it, but I'm running into a limitation that severely restricts the set of things I can do:

Gutenberg utilizes the Context API that was introduced in React 16 extensively throughout its built-in editor components, particularly to manage when a block is "selected" vs not. This context does not appear to bridge across the vuera embed.

The high level structure I'm using returns a VueInReact wrapped component to Gutenberg, with my core Vue component handling my custom logic, and then as necessary embedding ReactInVue wrapped Gutenberg builtins.

So we have
React (gutenberg, sets context)
-> Vue (my code)
----> React (gutenberg, looks for context and doesn't find it)

I'm happy to try to figure out/implement a fix for this, but would appreciate a pointer in the right direction if you have any ideas.

@kball kball mentioned this issue Jul 30, 2018
@kball
Copy link
Author

kball commented Jul 30, 2018

Digging into this a more, I haven't been able to track down how to programatically pull out a list of the Contexts that a component is embedded in.

Ideally I'd like to have the VueInReact wrapper grab that list (it's a normal React component that has access to existing contexts), stash them on the Vue instance, and then teach ReactInVue to look up its parent tree within Vue for contexts and plug them into place again.

Maybe @gaearon or @acdlite could help point us in the right direction?

@gziolo
Copy link

gziolo commented Aug 6, 2018

I get here from yout post @kball: https://zendev.com/2018/07/31/wordpress-gutenberg-blocks-vue.html 😃

What a nice coincident, I was working on refactoring one of the components mentioned in the article to use new Context API. To do it, I had to apply some updates to the custom serializer we built to make output compatible with WordPress specific rules. Related PR is here: WordPress/gutenberg#8189. It might be helpful for your explorations.

I think that the code that needs to be included in vuera can be found in react-dom here:
https://github.com/facebook/react/blob/master/packages/react-dom/src/server/ReactPartialRenderer.js#L938-L978

I might be wrong, not sure if the issue is with rendering, or with react itself.

@akxcv
Copy link
Owner

akxcv commented Aug 7, 2018

Hi, yes, I've been thinking about how to bridge React context across vuera. I think that the best solution is to render inner React components via portals instead of ReactDOM.render (only in React > 16). This should preserve context if I'm not mistaken.

@gaearon
Copy link

gaearon commented Aug 7, 2018

related facebook/react#13336

@haldunanil
Copy link

Any new updates on this? This is a significant limitation of vuera for us right now, where we're passing a theme prop via the Context API to components in our component library all styled using styled-components, but the components fail to render because of their theme dependencies.

@akxcv
Copy link
Owner

akxcv commented Sep 12, 2019

@haldunanil no, unfortunately, there haven't been any updates so far. What you could do in your case, though, is create a set of wrapper components instead of using Vuera as is. It would work something like this:

  1. Get theme from context and pass it down as a prop.
  2. Use Vuera to get from React to Vue.
  3. Get theme prop and assign it onto the Vue instance.
  4. (Do your things in Vue...)
  5. Get theme from the Vue instance and pass it down as a prop.
  6. Use Vuera to get from Vue to React.
  7. Get theme prop and assign it onto context.

I didn't try this at home, but it should be possible to create a sort of a bridge this way. Furthermore, such a bridge can be extended to do more advanced things in the future. It's also not cumbersome at all: if you do things right, all the bridging logic would be hidden behind a couple of components (one for React->Vue bridge, one for Vue->React bridge).

@haldunanil
Copy link

haldunanil commented Sep 13, 2019

@akxcv is there a gist or working codesandbox you can point me to? I think I follow your explanation but am confused how it would work in practice. I'm also not super familiar with Vue so I may be missing some stuff here.

@akxcv
Copy link
Owner

akxcv commented Sep 16, 2019

Sadly, I'm not aware of any gists or sandboxes. I'll try to experiment with this when I have a moment.

@haldunanil
Copy link

haldunanil commented Sep 16, 2019 via email

@Tofandel
Copy link

Tofandel commented Dec 26, 2019

React contexts is basically vue's inject/provide so this should be used instead of the suggestion to add props

I can have a look, it should actually be very straightforward to implement this

The wrapped component should invisibly pass the context to the child component by providing it and the Vue to react by injecting it, but the vue component could also use the context by using what's provided

React's api provide no way to retrieve all contexts though, so some React under the hood hack might be needed (which might break if they update the inner workings)

If there is no way to achieve this, the Portal api can be Used but then the Vue component will be completely unaware of context and a separate api will be needed to pass context to it

@tujoworker
Copy link

That would be awesome @Tofandel!

@Tofandel
Copy link

Tofandel commented Jan 6, 2020

So as it seems migrating this lib to a portal would be a huge undertaking, it is possible to access the full context using a react internal in v16: this.__reactInternalMemoizedUnmaskedChildContext which solves the only issue to this dev, as previously explained it might needs some checks because this property might be non existent or under another name in other react versions

Untested yet but the dev is on my master fork
Will do a PR when tested

@akxcv
Copy link
Owner

akxcv commented Jan 6, 2020 via email

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

No branches or pull requests

7 participants