App A is a self-contained, single-page React/Redux application that is meant to be pluggable into other applications (not necessarily written in React/Redux). I'm trying to embed app A in another single-page React/Redux app B as follows:
In app B, create a ponent, ComponentA, whose route is the same as that used by app A, and whose
render()
method generates aDIV
tag to host app A.In ComponentA's
ponentWillMount()
method, load the previously built js bundles for app A, by appending the corresponding<script>
tags at the end of the document body, which causes app A to render on the page.
This seems to work fine, however, when I navigate away from ComponentA and e back, I see the following error appear in the Chrome Dev Tools console as many times as I have accessed ComponentA: "Uncaught (in promise) TypeError: Cannot read property 'replaceChild' of null".
When I examine the "React" tab of the Dev Tools, I can see app A's ponent hierarchy appear multiple times, however, only the last one is actually attached to the physical DOM.
My guess is that when I navigate to other sections of app B (using app B's links), app A isn't aware of the route changes, so it is never unmounted, which causes some unintended behaviour and subsequent errors.
I'm new to the technology, and I'm wondering if it is even possible to embed a React/Redux app in another React/Redux app. If it is, then how could I change my approach to make it work properly?
I haven't included any code snippets for now, because the code is pretty standard, basic React/Redux code, and it's the approach itself that I question.
App A is a self-contained, single-page React/Redux application that is meant to be pluggable into other applications (not necessarily written in React/Redux). I'm trying to embed app A in another single-page React/Redux app B as follows:
In app B, create a ponent, ComponentA, whose route is the same as that used by app A, and whose
render()
method generates aDIV
tag to host app A.In ComponentA's
ponentWillMount()
method, load the previously built js bundles for app A, by appending the corresponding<script>
tags at the end of the document body, which causes app A to render on the page.
This seems to work fine, however, when I navigate away from ComponentA and e back, I see the following error appear in the Chrome Dev Tools console as many times as I have accessed ComponentA: "Uncaught (in promise) TypeError: Cannot read property 'replaceChild' of null".
When I examine the "React" tab of the Dev Tools, I can see app A's ponent hierarchy appear multiple times, however, only the last one is actually attached to the physical DOM.
My guess is that when I navigate to other sections of app B (using app B's links), app A isn't aware of the route changes, so it is never unmounted, which causes some unintended behaviour and subsequent errors.
I'm new to the technology, and I'm wondering if it is even possible to embed a React/Redux app in another React/Redux app. If it is, then how could I change my approach to make it work properly?
I haven't included any code snippets for now, because the code is pretty standard, basic React/Redux code, and it's the approach itself that I question.
Share Improve this question asked Jan 5, 2018 at 0:04 pikkabirdpikkabird 1373 silver badges10 bronze badges 2- Thank you for explain but would be nice to send some code to see this implementation and look for issues. Just for curiosity, why did you do a single redux app of both? you can get a JSON or state of one app and put on another one and you will have a single source of thurth, less plexity, less problems. – Jan Cássio Commented Jan 5, 2018 at 3:19
- @Jan Cássio: Thanks for replying. I decided to do some more research and was eventually able to fix the issue (see my answer below). As for your question, assuming I understood it correctly, the hosting app (B) is an existing app, so I had no control over its code, and app A is meant to be a self-contained, single-page app, for simpler integration with other apps. – pikkabird Commented Jan 6, 2018 at 1:48
1 Answer
Reset to default 5I was able to resolve the issue by modifying the code in app A's entry point and changing how the app is built.
Before the fix:
- App A was built as a self-contained, self-rendering application.
- App B's ComponentA was adding app A's bundle script tags in its
ponentWillMount()
method. - App A's entry JSX was executing
ReactDOM.render()
immediately, and there was no way to unmount it from within app B.
After the fix:
- App A is built as a library (specified as such in the Webpack config).
- App A's entry JSX defines the library interface, exposing custom
new()
,render()
, andunmount()
methods. - App A's bundle script tags are hardcoded in app B's index.html.
- App B's ComponentA:
- in
ponentWillMount()
: instantiates app A. - in
ponentDidMount()
: calls app A's render(). - in
ponentWillUnmount()
: calls app A'sunmount()
, which callsReactDOM.unmountComponentAtNode()
.
- in
I'm now seeing only one instance of app A's ponent hierarchy in the "React" tab, and no more errors appear in the console.
For anyone interested, the fix was inspired by the following article that I eventually came across: https://codeburst.io/building-react-widget-libraries-using-webpack-e0a140c16ce4
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744230405a4564219.html
评论列表(0条)