Consider that there's a tabbed accordion, user can open one tab at a time, rendering each container take more than 100 milliseconds (sometimes like 1 second). How could I implement such a thing that user don't feel lag every time navigating between tabs and first time rendering won't be slow as well?
I'm thinking of these ways to do that:
Detaching element (or caching)
Implementing something like shouldComponentUpdate but for first time render
Some middle-way component that won't render if tab is hidden in first render and won't update if currently rendered tab is hidden.
Check if tab is rendered before and don't add it if it's not active and not rendered
Is there any library or Component that do such a thing? Or how can I implement one of these?
P.S: That's not only about performance, there's scroll position, user interactions that needs to be preserved when switching between tabs (like an input that is changed in one)
Related
I am working on a nextjs/react app building a page that renders a list of items. Each item has a button that opens a Drawer with information regarding this item.
What I did was attaching a Drawer to each item with its own content. This works fine but I am concern about the performance.
My second option which increases the complexity (as I might need to use context) was creating a unique Drawer component that changes its content everytime a different item's button is clicked.
The page will have pagination which means the list won't grow too much so I was wondering if using the second approach will significally improve the performance/size and how this could be measured.
I have written a react component composed of two child components. All three are functional components which utilize hooks.
Think of a visit to Amazon searching for a video card. On the left are filters you might use: resolution, type of connection, number of connections, etc. As you choose filter values the component to the right displays applicable thumbnails for those items matching your selected criteria.
When clicking on one of the thumbnails, the parent and children (filter and thumbnails) windows are replaced with a detail component. The original window is not visible. Hitting the back key, the original components, including the selected filters and thumbnails, should be as before.
However, when hitting the back-key, the original component with its children displays without any of the selected filters.
I am using react v16.11.0 and react-router-dom v5.1.2.
Clearly I am lost. Can anyone suggest an approach?
I used rather than . The router was not recording the transition in history. I was already at the route to which I wished to navigate before hitting the back-key.
This Is more of a "theoretical" question that often buffles me in different situations and use cases, I will give a simple example to demonstrate it.
Let's say I have a list of 10 buttons.
Everrytime I click a button, a floating menu appears on top of the clicked button - there is only one menu visible for any given time.
Let's assume that I can't render this floating menu within the button component and I can only render it in the buttons parent level (meaning that this menu is sibling to those buttons).
I have 2 possible options to do that:
Keep the x,y position of the last clicked button and render the menu in this given position
Render the menu once and using "ref" to directly relocate the menu
On the one hand, the first approach seems more "Reactish". On the other hand, the possible implemention I can think of is pretty ugly (capturing the clicked item position and saving it to state which triggers defender), and further more, I am not so sure about re re rendering the whole container just because I need to move a small piece of it.
The second approach touches the DOM directly using refs. Although possible , doing DOM manipulations sometimes feel bad to me.
Is there a better approach? Which of the 2 makes more sense?
Any suggestion or thoughts will be appreciated!
Thanks
React uses whats called a virtual DOM, which is a representation of the DOM, that sits on top of the real browser DOM. Whenever you update state or a user performs an action the virtual DOM compares and checks the changes with the real DOM and then updates the UI accordingly.
So if certain DOM elements like a are not different between changes it does not get re rendered, only the DOM elements that have changed are re rendered. And if a property on a DOM element is changed, only the property is updated and the DOM element is not re rendered.
<div color="blue" />
to
<div color="red" />
The whole element is not destroyed and re created, only the property is changed.
However if the element in the host tree is different than the entire host tree is destroyed and recreated.
<div />
to
<p>
This is refereed to as reconciliation
https://reactjs.org/docs/reconciliation.html
So using refs is definitely more of a hacky solution since its more of an escape hatch and directly manipulates the DOM.
I would definitely stick with option 1, I think there is an elegant solution to the use case you described, it would involve just adding a click event listener in the componentDidMount and keeping track of the click position that way.
And also its hard to say without code but since your buttons will be the same, they will not be re rendered only the menu will.
Would recommend for further reading
https://overreacted.io/react-as-a-ui-runtime/
I used react-infinite-scroll-component it's working just fine.
However, I want to avoid making the user lose his scroll position when he leaves the page and clicks back?
Also please put on consideration Firefox and Safari.
Not 100% sure because I haven't used it - but since no one else has chimed in... the docs say the component has a prop named key that is described as:
the key for the current data set being shown, used when the same
component can show different data sets at different times,
default=undefined
Also, it has a prop named onScroll that is described as:
a function that will listen to the scroll event on the scrolling
container. Note that the scroll event is throttled, so you may not
receive as many events as you would expect.
... which I suspect one of the arguments of which will tell you which keys it loaded / scrolled through.
So my approach would be to use componentWillUnmount to save the last key it loaded into a parent property (or Redux store if you're using Redux)... and when the component loads, if the key exists in the parent (or Redux store if you're using Redux) then pass it that key.
I am learning to react native and I found the following term on this documentation.
If you have a long list of more items that can fit on the screen, you should use a FlatList instead.
Which means that the FlatList component is used for a flat list that is fit on the screen and not scrollable. But on the FlatList documentation it says:
The FlatList component displays a scrolling list of changing, but similarly structured, data.
Please, can anyone tell what does it mean? Because both documentations are going opposite.
There is a lapse in your understanding of the sentence from the first documentation link. It actually says:
If you have a long list of more items than can fit on the screen, you should use a FlatList instead.
Notice that it says than instead of that which are totally opposite of each other. The phrase than can fit on the screen means that you have items that cannot fit within the current display size, so using FlatList is recommended.
Both ScrollView and FlatList are scrollable components. Some differences are:
ScrollView is a lot more generic. You can nest any sort of component within a ScrollView and they won't complain. FlatList on the other hand accepts similarly-structured data.
Components contained within a ScrollView will render together when it loads. FlatList will only render its children which are within the scope of the screen, and render the remaining ones when user scrolls to them.
UPDATE:
When I say 'display', I mean the phone's actual, physical display, and by 'container' I mean the set of components/items which make up your app's current page, like a combination of text inputs, buttons, views, etc.
Consider the following Log In form (source):
Every item (component) in this container screen is visible on the phone's display since there aren't a lot of components to begin with. You can get away without using the support for scroll here.
However there a lot of times when you have a lot of components in your container but the display can only fit a limited number of them at a time. Rest of the components would, sort of, spill out of the phone's display. In those cases, you must use a scrollable component to properly display all of them, and so that your app's user can actually reach the components which are out of display's current range. For example an inbox with many messages, or a to-do list with many items:
In the image above, phone's display can only show first 6 items in the inbox. What about the rest of them? Of course you have to scroll to see them! You may use ScrollView or a FlatList to enable the support for scrolling here.
Now, if you use ScrollView in these cases, all children (inbox items) within the container will load when this particular app page loads, i.e. at the same time. Consider an inbox with 3000 items. It would take forever to load all of them at the same time! The user would be waiting for a long time for them to load. Therefore, a simple ScrollView won't work here.
Fortunately, we have FlatList for that.
When you use FlatList to display scrollable components, only a limited number of items will render at a time which can fit the current display (say, 6 items in the example above). What about the remaining 2994 items? FlatList will render them dynamically as the user keeps scrolling down.