Closed MrAvantiC closed 5 years ago
Without having had a deeper look into this: Did you try and compare the React Sample Project? It does not utilize the Webpack adapter, but also uses the Context API https://github.com/dennisreimann/uiengine-sample-react/blob/master/lib/uiengine/react.js
Well, as far as I can tell, the Webpack adapter doesn't offer a similar hook like wrapElementBeforeRender
, does it?
I tried to imitate that functionality by utilizing the renderers like that:
// react-server-render.js
module.exports = function serverRender(Component, props) {
return renderToString(
<ThemeProvider>
<Component {...props} />
</ThemeProvider>
)
}
Not sure if that's the best way but it did insert the ThemeProvider
into the component tree atleast. Just accessing its provided context doesn't work.
Yep, I have tried several ways now, but I also can't get the ThemeProvider
to update when it is passed the value
prop. I am not really familiar with the React Context API, but from what I saw in the docs it should be working :(
Damn!
but I also can't get the ThemeProvider to update when it is passed the value prop
Does that mean you were able to access the this.context
in the Class Component but it (just) didn't update?
Because in my tests this.context
wasn't even defined (probably not passed through by the webpack build process?) in the Component.
It is defined when you initialize it with React.createContext(‚initial value‘)
, but that does not help.
Had another look earlier today and my guess is that it boils down to the same problem as mentioned in #46, namely that somehow stuff specified in the render files is not accessible in the variants, because they are two separate files and not bundled together.
You can see this when you are using the latest versions (2.4.x) and have a look at how they are build (dist/_webpack) and integrated in the HTML.
Don‘t know for sure, but that‘s what came to my mind as the most likely thing to cause this.
namely that somehow stuff specified in the render files is not accessible in the variants
I don't quite understand this point. After all, the variants do require the actual components ...shouldn't that be resolved by webpack?
Unfortunately, my webpack knowledge is kinda limited. Do you see any possible solution to this - like packaging them together somehow?
After all, the variants do require the actual components ...shouldn't that be resolved by webpack?
That's correct. Nevertheless, currently the variants and render functions (serverRender
and clientRender
) live in separate bundles.
See the source of this example for instance:
<script src="/_webpack/jsx-client.js"></script>
<script src="/_webpack/src_elements_label_variants_label_jsx-client.js"></script>
<script>
window.UIengineWebpack_render(
window.UIengineWebpack_component,
{"id":"name","title":"Name"}
)
</script>
This is the generated output:
UIengineWebpack_render
UIengineWebpack_component
They aren't bundled together and from what I have seen so far, this is the problem with the React hooks and context APIs. They seem to rely on side effects that require both files to share the same scope (and by that the exact same React instance).
I'll tinker more with that when I find the time to do so :)
No worries, we'll figure out a way that works for our use case. :) Appreciate your commitment!
I got it kinda working – at least on the client-side. Same problem still when rendering server-side, which I don't understand yet as the React instances there are the same too.
However, as I am still unsatisfied with the approach I'm taking to make this work and I am still trying to find a better way, here is something I can imagine to work for you in the meantime: Use the Webpack externals option to extract React and ReactDOM from the bundle:
externals: {
react: 'React',
'react-dom' : 'ReactDOM',
}
You would then have to provide them via CDN or local linking in the preview uiengine.html template.
Hey Dennis, I tried excluding them from the build (which worked) and included them via CDN: https://github.com/MrAvantiC/uiengine-context/commit/29457cf429a07137c78b4d764f93ef48e95c8d77
Unfortunately, accessing this.context
in the Component still returns undefined.
Am I missing something?
Ok, took another look and I really don't know enough about how this is supposed to work to fix it. I'd appreciate someone having a deeper look and assisting me with debugging that.
From what I saw the problem seems to be that the context cannot be shared across React instances coming from different bundles.
For reference:
Status update: I got it working now :)
Will clean up the code and test whether or not this helps with the hooks issue as well during the next days.
See the example here: https://uiengine-sample-project.uix.space/testcases/examples/ReactContext/
v2.5 is available now and fixes this :)
Hey Dennis! Sorry for this neverending story, but I have another problem using the jsx/webpack adapter. :/
Describe the bug We have a use case where we need data available to every component. To avoid "prop drilling" we want to make use of the Context-API for this.
I tried to make use of the
react-server-render
andreact-client-render
for this to make the context available to every component/variant in UIEngine. This looked good at first, since the Context-Provider showed up in the component tree:Unfortunately, the actual context is not accessible in the components of the UIEngine. It appears like the context is not passed through to all the underlying components.
To Reproduce Steps to reproduce the behavior:
render()
method in<Footer />
Expected behavior The context should be available in the
<Footer />
component. I can confirm that the same code works in CRA/Next.js.Kind regards, René