Stop scroll bar from moving to top when rerendering reactjs - reactjs

I am trying to create a panel where a list of item is presented, once an item is clicked, the right hand side should display the item selected. The left hand side should contain a list of items. The list of items can be very long therefore, i have limited the max height of the list such that when it exceeds this height, it will create a scroll bar so user can scroll down to see the rest of the list. The problem is, whenever an item at the bottom of the list is clicked, the list automatically scrolls back up to the top. I have a feeling that this is due to the fact that I am using a state to pass the item around, and when the item is changed, it causes a re-render thus "reseting" the list. Can someone give me a suggestion as to how i can stop this from happening? Any pointers would be greatly appreciated!
Here is the sandbox:
https://codesandbox.io/s/sad-archimedes-3u4k0?file=/src/App.js
ex/ scroll to the bottom and click "random30" and the list goes back up to "random1"

This happens because you placed a component EventListContainer inside of EventsList component which will lead to "re-render" every time you update the state.
You can just move ScrollContainer directly inside the EventsList component return:
return (
<ListContainer>
<ScrollContainer>
{eventListSorted.map(event => {
return (
<EventContainer
onClick={e => {
onSelect(event);
setSelectedEvent(event);
}}
selected={selectedEvent ? selectedEvent.id === event.id : false}
>
{event.uiString}
</EventContainer>
);
})}
</ScrollContainer>
</ListContainer>
);
Also you better move the eventListSorted array outside the EventsList component.
sandbox example.

Related

How to set ReactiveSearch loader position to top or bottom?

I'm using ReactiveSearch 3.30.0.
Here's how I use the ReactiveList component in my Next.js project.
<ReactiveList
....
infiniteScroll={true}
showLoader={true}
pagination={false}
loader={<MyCustomLoader/>}
....
/>
The problem is during the loading that occurs,
When I click on a filter item
or
When Scroll more to the bottom
the MyCustomLoader is always at the bottom.
Expected outcome for the MyCustomLoader is,
When I click on a filter item => MyCustomLoader at top
and
When Scroll more to the bottom => MyCustomLoader at bottom
The reason is, since my results list is long and scrollable, the loader is not shown when I click a filter item. It is actually rendered on the DOM, because I could see it when zoomed out the browser window (but is outside visible area to the user).
Related GitHub issue https://github.com/appbaseio/reactivesearch/issues/749
Any workaround is highly appreciated. Thanks.

How do I detect when FlatList has rendered all items and actually scrolled to bottom?

I'm passing a very long array into a FlatList.
FlatList dynamically loads more content as you reach the bottom.
I have a ListFooterComponent that indicates whether the user is about to see more data.
How can I know when the FlatList has truly rendered all items and therefore has reached actual bottom of scroll? Then this footer component will show something like "You're at the end of the list!"
FlatList component has a callback function that is called when the list reaches the end or the specified threshold.
<FlatList
...
onEndReached={() => {console.log('list ended');}}
/>
FlatList - onEndReached

Hidden material UI still rendering element

I am trying to conditionally hide a material ui component.
My first thought was that I'd simply not render the element at all (given I'm not purely hiding it due to 'breakpoint' reasons)... but according to the documentation for the mateiral UI Hidden element here: https://material-ui.com/layout/hidden/
This has the benefit of not rendering any content at all unless the
breakpoint is met.
Score, that sounds great. I could say the Hidden element applied when larger than xs and smaller than lg and it'd have the effect of always hiding the component when applied.
However, when I wrap a component in a hidden element using this code:
let withPaper = <Paper>{this.buildQuestion()}</Paper>;
let withToolTip = withPaper;
if (tooltip != null) {
withToolTip = <Tooltip title={tooltip} enterDelay={500} leaveDelay={200}>{withPaper}</Tooltip>
}
let withHidden = withToolTip;
if (this.props.hidden) {
withHidden = <Hidden xsUp xlDown>{withToolTip}</Hidden>
}
return withHidden;
only the visibility appears to change. It still takes up space on the screen. Look at the following two screenshots. You will notice that the "Station Number" text field shows up when the Hidden is not included and it's invisible when it is included... however, the component is still taking up space in the material-ui Grid.
(ignore the messed up vertical alignment)
Without the Hidden component on the station number:
With the Hidden component:
Based on the documentation, this doesn't appear to be the normal/correct behavior.
How can I get the wrapped component to completely not impact anything on the screen (hopefully while still being able to access it's values and props?)?
Turns out my component was sitting in a grid item (https://material-ui.com/layout/grid/) so, while the Text Field wasn't actually rendering... an empty grid items was.

scroll to the list's top when hide the modal

I used react-virtualized to create a infinit list component and antd to create a modal component.List item bind the click event to show the modal.
hrer is demo's link: https://codepen.io/dingjs/pen/eRXZyw?editors=0010
Dont't scroll
Click list item (The modal will show)
Click close button of modal (Window will scroll to the top of list)
Scroll to top of window
Click the element out of list then close the modal(Everything is all righ)
The question was Occurred in the third step.
If list's header under the top of browser, window will scroll to the top of list.
You did not explicitly say what your actual question is, but guessing from the title you want the window to scroll to top when the modal is closed. But that is so simple that I am thinking your actual question is something different...?
Put a
<div id="topOfList"></div>
at the start of the list, then
close = () => {
this.setState({
visible: false
})
document.getElementById('topOfList').scrollIntoView()
}

How can I scroll to to the top of a "simple" react-list when it's redisplayed?

I'm using react-list to display lists data within Material-UI Tab components.
I'm using the simple type in the list, e.g.
<ReactList itemRenderer={::this.renderItem}
length={this.props.contacts.length}
pageSize={20}
type="simple"
useTranslate3d={true} />
I have to use simple as I don't know the size of the rendered items.
This means I can't use scrollTo fully. From the docs
Note that if you aren't using type='uniform' or an itemSizeGetter, you will only be able to scroll to an element that has already been rendered.
When I'm work with the list on one tab and scrolled, say, half way down, when I switch to another tab, I'm scrolled some way down the list that has been updated with the new data.
What I'd like is to have the react-list reset to display the first item when I switch tabs.
I've tried putting a ref in ReactList component and then calling scrollTo---like this
ref={c => this.list = c}
componentDidUpdate() {
this.list.scrollTo(0, 0);
}
Had no effect.

Resources