Decoupling UI components in React - javascript

I am new to React but have not found a suitable solution to my first problem on the job.
The specific context is of a navigation component that composes several other components and together they are a redistributable unit, independently testable as a whole module.
The use case of the component is to sometimes render it in desktop mode using React media queries, and other times in mobile - in which case it needs decorated with flyout behaviour.
So I want to decouple the navigation component from having to know about flyout. In respect of the 'tell don't ask' principle or event driven I want to be able to notify a parent that navigation has changed and depending on how this component is implemented respond accordingly (in mobile, the flyout needs to get hidden, in desktop there is no flyout decorator).
I looked at redux-ui which is a nice syntactic sugar using annotations but falls down when a property it is trying to set in the state hierarchy doesn't exist. And besides, this breaks the decoupling model.
I am a little abstract here I realise but does anyone have a recommendation on how I might approach this? I suspect that a possible solution might involve not having a hierarchy (is-a) imposed by the decorating wrapper and rather has-a flyout capability but would welcome industry experience on this.
Thanks

There are a few ways to handle this. The simplest would be to do it purely in CSS. Have all the HTML for the component always in the component and only the CSS would know about mobile or not.
Alternatively, you could have a piece of global state that gets set when the app loads and tells the app whether it's on mobile or desktop, and then pass that down to any relevant components. This method would be a bit of a pain because 'mobile' and 'desktop' are really just 'small screen' and 'larger screen' and as a result, this may change while the user is in the middle of using the app (like changing screen size, for example). So you'd have to keep track of all that with a bunch of listeners that are constantly listening for window resize events.
The simplest solution does seem to be pure CSS here.

Related

When is it safe (if at all) to manually relocate a Vue-rendered DOM node?

I understand that you should not manually manipulate the DOM nodes rendered by a Vue component for reasons including:
After another render, Vue can override any changes you did
It can interfere with Vue's patching algorithm
My use case is I would like to implement a way to move a DOM node to a separately-controlled location for the purpose of displaying it fullscreen. Imagine an editor widget with a fullscreen button that "pops out" the editor and overlays it fullscreen.
I understand that I can achieve this with CSS alone using fixed positioning, but I'm not interested in that, I'm particularly interested in the consequences of moving the DOM node out from wherever it is and appending it directly to the <body> element. Will Vue still be able to patch the nodes correctly after the parent component re-renders?
I have experimented with this already and I have a working implementation, and I haven't encountered any issues yet. Still, this doesn't ease my concern, and the Vue docs don't talk about doing something like this.
What potential issues, if any, might I encounter?
portal-vue is unsuitable because it recreates the component instance each time it is relocated, which I do not want.
Depending on how the component lifecycle works in Vue, moving a component in the DOM might trigger lifecycle methods. E.g. with Custom Elements, moving means triggering disconnectedCallback of the component, and subsequently connectedCallback. This is often where the component initialization takes place.
Rather than moving the component manually from the outside, consider giving the component itself the ability to relocate.

Correct way to hide components in React.js

Say you are passing a prop called show to a component. If the prop value is true, you should render the full component normally. If it is false, you should not display anything.
You can do this two ways.
return null in the render method of the component.
apply a CSS class containing display: none attribute to the component's DOM element.
Which ones is the correct or the preferred way?
I do not think there will be any definite answer for this question.
Each approach has its benefits and drawbacks.
With CSS you have:
it might work faster
no need to think about restoring child control states if control is shown again.
With returning null:
the total rendered DOM might be considerably smaller. This is important if you have many such components that might be hidden.
there will be no collisions in rendered html. Lets say you have tabular view. Each tab is its own complex form with many child controls. If you have some raw javascript/jquery/whatever working with their ids/classnames etc. - its quite hard to ensure each tab/form has unique ids, unless you do not render them.
From my point of view the decision will be based upon the structure of your control. If it have complex structure with many nested children and you do not have any means of restoring their states when switched on again - go with CSS, but I would say this is a short term solution for quite simple controls only. In all other cases I would go with not rendering a component.
If you think you would need to display the component again, during that page life, then I would recommend using css way, as the impact on DOM manipulation would be less in that case. In some other cases probably returning null would be more helpful.
For the most part, your two solutions are interchangeable. They both "work" fine.
I would warn against preemptive optimization in choosing which of these methods to choose. If you do need to eventually modify your code and try the other method, this is an absurdly simple swap to make and shouldn't be an obstacle. So don't worry about it until there's a reason to worry about it.
I'm the OP.
If components are hidden depending on the screen size, CSS media queries and display: none works the best if the app is pre-rendered using something like react-snap. This is because, if the pre-rendered device and the viewing device don't match, the layout would change when the app rehydrates if the component hiding logic is in JS.
Related to that, we need to be careful that even though the component is not "shown" with CSS display: none, the component is still there and if there are effects, they will still fire.

Render all possible elements or render on request

So I have an app that has a right sidebar whose visibility is toggled via a button. In that sidebar there can be one of several things [at a time] - chat, help, search. I was looking at some plain HTML from apps which have a similar feature and noticed that they have all nodes rendered, but are just hidden via CSS.
Since I need to do the same thing, I was thinking whether this would be a good idea to do with React. But then I realized that React elements have a state which when updated calls the render method. So I can use the state to store both whether the sidebar is opened, and what is inside the sidebar.
Is that the React way of doing things? Is it better to have all nodes rendered even if they are not visible, or is it better to have the nodes rendered on request via state changes?
My feeling is that only rendering what is visible would be the more standard React way, but in this case, this is mainly a performance decision. If you render everything and just toggle visibility with CSS, the first render will take longer (but the time difference may not be relevant or even noticeable). If you render only the part that's visible, React needs to do a small rerender every time the sidebar content changes. (This may also not be noticeable time.)
My recommendation would be to try both, if you want to test the performance. But I think you won't go too wrong either way.

Limiting React render calls in components?

I have an UI built in Flux/React that mimics an OS windows system. User can move, minimize, and resize windows but also drag'n'drop icons between windows. I have main Desktop component which polls LayoutStore and builds children based on layout data.
It turns out however that rerendering the virtual DOM tree with more elements takes long enough to impair app responsiveness sometimes which is bad for transition animations. I already gave up on updating state at 60fps - I just update layout store after user drops an element. I was thinking about ways to limit render calls since I know that most changes to the layout affect child components very selectively - there is low chance that a given layout state change affects more than one particular component.
What I came up with is keeping a dirty or stateVersion variable in LayoutStore for each larger component (i.e. a window) and passing it in props so that each component could check if it was affected very fast without worrying about complexity of state representation (no deep comparisons, immutable copies, etc.) Also I prefer the second way cause I can just bump component's stateVersion each time I mess with its properties and don't need to unset dirty back in the store after emitting change.
Since I'm very new to React - is it a sane approach given my constraints or is there a better standard solution?

communicating between iframe and parent window?

in an article where Sencha disputes facebooks claim that html5 is slow,they suggest that there's a way to create a framework that would allow for seamless communication between an iframe and the parent window. How would this be achieved? not looking for code examples, just ideas. thanks
So the Fastbook app is the first to make use of a brand new “Sandbox
Container” which programmatically detaches complex views and renders
them into their own iframes, and thus partitioning the DOM tree. This
special container doesn't need any extra handling at the application
level, so it's seamless to developers (i.e., any component added to
this container will be sandboxed automatically). But it does come at
a cost: events, positioning, styling, and JavaScript code have to be
proxied between the parent window and the child sandboxes. This is
complicated, so without a robust and properly architected framework,
it is very difficult to implement. Sandboxing allows layouts to be
isolated, and therefore keeps the primary DOM tree as light as
possible. To bring balance to the Force, Sandbox Containers must be
used wisely
.
something like http://easyxdm.net/wp/ takes care of it by using PostMessageTransport

Categories

Resources