A12 Module re-creating view from scratch on redux store update

Hi,

in our React app, we have a Module which renders custom views.
While the custom views are on the screen, the redux store is updated (through an HTTP request which stores its result in the store).

Our “PoolModule” looks like this:

function viewProvider(componentName: string): React.ComponentType<View> | undefined {
	return Views[componentName];
}

const Views: { [name: string]: React.ComponentType<View> } = {
	PoolDetails,
	PoolProjects,
};

const module = (): Module => ({
	id: "PoolModule",
	model: (): ApplicationModel => model as ApplicationModel,
	views: () => viewProvider,
});

export default module;

In the appmodel, we directly show the view, like so:

"sceneChange": {
  "onEnter": [
    {
      "type": "VIEW_ADD",
      "name": "PoolDetails"
    }
  ]
}

The problem that we experience is, that on any redux state update, the complete PoolDetails component is unmounted, and freshly created again, re-creating also all child-components in its sub-tree. PoolDetails itself is however not depending directly on anything from the store…

Now, our question is if it is normal in A12 that a View declared in the view components of a Module is re-created on every redux store update?
Or are we just doing anything wrong on our side?

How do register the module?

In another thread (regarding the use of react router) you embedded code of a react component that registered the module in its render code. This might be executed too often since it will do the registering whenever this component updates (for whatever reason).

In my opinion, registering the modules should usually be done in a central configuration unless it is really important to be able to dynamically add and remove the modules.

The reason could be a totally different one, though. It’s hard to tell from your given information.

Thanks for the reply, that was a good point.
However, I just dug into the mounts/unmounts of all relevant components in the tree, starting from the parent of the component that registers the module (using useEffect(() => {...}, [])).
The component that registers the module is not re-created when the redux store is updated, thus the module is only registered exactly once (on mount of that component). However, going downward from the RegionUi/customLayoutProvider (which we left unchanged), the very first component that is completely re-created is exactly the custom view PoolDetails. And from there, the re-creation goes downward to all its children.
This is actually a strange behaviour, because I would suppose that the tree-structure stays the same across store updates, and React should thus not re-create all elements from PoolDetails downward…

Exactly, we use that approach.

In our case it is indeed necessary (as far as we understand), because we want to render certain models on certain pages, which have nothing to do with each other. With the default approach of registering all models at the beginning, A12 would render ALL models on any RegionUi that we would put on any page. Which is exactly why we came up with this “register/unregister modules per page” approach.

@erik-radiant-gorge hi,

we are still stuck at the same point and are currently not able to implement our desired functionality…

We did further research about this topic and tried to set up a vanilla react project, with the same redux store and components. The difference is clear:
The plain react app doesn’t have the problem which I mentioned above. When performing a store update there, it won’t ever re-create all components from scratch, but rather just re-render the ones that actually depend on the respective store state.

In our A12 react app however, the entire custom view PoolDetails (defined in the viewProvider of our module) is re-created (unmounted, disposed and freshly mounted) on every store-update that happens.

I will now try to reproduce the same behaviour in the fullstack-template…

If you said that re-renders are unexpected I would have looked at the props of the PoolDetails view which is the View interface.
This contains different (static) configuration from the application model + activity + optionally ariaLevel and a progress component.
There the most likely cause would be a change of the activity I guess. (Maybe data from the HTTP request?)

However, unmount and re-mount would occur if either the parent component is no longer rendered and thus the whole component sub-tree below is gone, or there is conditional code in the parent component that either renders or does not render the respective view component.