Unrender component created by ReactDOM.render when the container is unrendered - reactjs

There're two component developed in two different application.
One is App. Another one is MFE1.
In real world we have MFE2, MFE3, MFE4...etc. And App is just a container.
We will load different MFE into App using ReactDOM.render(Match by id).
The whole thing is actually working fine but there's only one existing issue.
We cannot find a way to unrender MFE1 when its container is unrendered.
I tried to call unmountComponentAtNode inside the useEffect callback of the App container.
However since the DOM is already gone at this point so we cannot use this method.
At its simplest level, my question is how can I unrender the MFE1 when/after I unrender its container?
I have created a sandbox to simulate the issue.
https://codesandbox.io/s/zealous-black-7swzbt
Inside the sandbox, I already implemented the way we load these MFE1 into App.
There's two buttons inside the sandbox.
Button switch mfe simulate the way we switch between different MFEs.
When you click it, you will see the MFE1 is invisible in the page, however it is not unrendered yet since the console.log("MFE1 is unrendered") is not called.
Button unmountComponentAtNode simulate the expected behavior, you can see MFE1 is invisible in the page, also the console.log("MFE1 is unrendered") is called. However I cannot use it inside the useEffect callback...

Related

Running react app in browser issues with saving and editing

When I run my react app in the browser, everything works fine. But when I edit a file and it gets saved, I can still see the whole app but when I try to interact with it, it doesnt work, I did inspect element and saw that the body that does not contain anything. Yet the content is visible?
Any solutions?
Note , when I reload the page everything is working fine, but its annoying to have to reload the page everytime.
Next JS is based on Reactjs and this might be helpful for you:
Limitations
Fast Refresh tries to preserve local React state in the component
you're editing, but only if it's safe to do so. Here's a few reasons
why you might see local state being reset on every edit to a file:
Local state is not preserved for class components (only function components and Hooks preserve state).
The file you're editing might have other exports in addition to a React component.
Sometimes, a file would export the result of calling a higher-order component like HOC(WrappedComponent). If the returned
component is a class, its state will be reset.
Anonymous arrow functions like export default () => ; cause Fast Refresh to not preserve local component state. For large
codebases you can use our name-default-component codemod.
As more of your codebase moves to function components and Hooks, you
can expect state to be preserved in more cases.
You can read more about FastRefresh from the documentation.

Block page change

I have a problem with blocking page changes in the application. The application is written in react and installed in liferay (CMS). It wants to keep the user on the payment intermediary selection screen. Unfortunately, the methods I know do not work properly. Blocking on the "beforeunload" event only blocks the closing of the page or its refresh (I'm only interested in closing the tab, but it is an additional condition). Blocking the website by react router doesn't work properly either. The prompt component works only within the scope of the added page, and no longer works in the navigation created on liferay. This is the same for useHistory (history.block('msg')), because it works just like the prompt component. I also tried to get this effect with other events, unfortunately to no avail. Does anyone have an idea to solve this problem? Thank you in advance.
I'm not aware about Liferay navigation behavior but I can see two resolutions:
you could go on using react router to block the transition to another route:
You could find a full example on the official docs (https://reactrouter.com/web/example/preventing-transitions).
<Prompt
when={isBlocking}
message={location =>
`Are you sure you want to go to ${location.pathname}`
}
/>
if there are parts of your application not handled by react-router you could rely on some event from history, like the one described here:
https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate
A popstate event is dispatched to the window each time the active history entry changes between two history entries for the same document.

Trigger Google Optimize experiment or any tag on click event in child or parent component, Application is build on Meteor React Redux

I'm currently facing an issue with Google Optimize, Application is build on Meteor React Redux, if there is any way to trigger Google Optimize experiment or any tag on click event in child or parent component, experiments are getting triggered on URL basis but, I'm not to add variation for click event at component level.
Suppose there is Cart button on clicking Cart button slider will open in same page, I have to apply Google Optimize experiment for the slider component.
Thanks in advance.
There are two key steps you need to take, to make this experiment work.
First, you have to set up the experiment triggers. By defeault, experiments start on page load, but this can be changed to so called custom events. Further details are available here.
Second, you need to dispatch this same command, when the relevant event (click on the Cart button in your case) has happened. More precisely, you need to send this event into the datalayer, using the following command.
dataLayer.push({'event': 'optimize.activate'});
You can customize this event name at the Optimize settings. In this case, the event in the datalayer call has to be aligned.

Issue with UI event when rendering component inside a web component shadow DOM

I'm facing some issues when rendering a React component into the shadow DOM of a webcomponent.
I wrote a small piece of code to turn a React component into a webcomponent, but I want to render the
React component inside the shadow DOM of the webcomponent. But in that case, it seems that React is not able to catch UI events (click, keyPress, etc ...) anymore.
Let's take an example, let say that I have a first webcomponent <awesome-timer /> that render the React component inside the webcomponent node, and another webcomponent <less-awesome-timer /> that render the React component inside the shadow DOM of the webcomponent.
Both webcomponents use the same React component. However the one rendered inside the shadow DOM does not work, because click events on the button of the timer component does not trigger the bound function.
I guess React is not designed to handle such case, but I'd love to get more details about it.
The code of the example is available here : https://gist.github.com/mathieuancelin/cca14d31184bf4468bc1
Does anyone have an idea about it ?
I know this is kinda late but, I believe your issue when you pass any attributes to a web component they instantly become strings Because that's all you can pass to a web component. Now of course you can convert or cast them back to there original data type, except functions because once stringified they loose there scoping, lexical and all.
Now to your main question, you are were trying to pass you child element through the Main web components slot. Now you have to remember that once you pass anything to a web component you now have to use the webs components methods and return types to manage whatever you pass. So yes passing react into a web component will not work they you expect.
You will need to go back to whatever tool you use to build your web component and deal with the slot logic there. Since this is a very old post as are web components. You might not have had access to the modern web component build tool's we have today. I found Stenicl allows you to build and manage your web components in Typescript.
A good option is to change your pattern a little bit and just return web components from your react app.
Or you can use another really cool to call Lit-HTML or Lit-element. I believe they may have combined there core libraries. Anyway these tool will allow you to combine Reactjs and web components where lit-html gives you access to methods simial to Reactjs's life cycle methods. Anyway some good stuff to check out if your stuck at this point.

ReactJS simulating events from different context

I am aware of React Test Utils that can be used to simulate events when testing, however I have a browser extension that doesn't have access to the context of the page. I would like to be able to interact with the DOM (click events and filling out fields), however it seems that the state is not updated by a page running with ReactJS. Is there a way to this at all?

Resources