5

is it possible to get scroll position in material-ui list on Scroll, if so, how?

I am trying to add infinite scroll on the select list since I have 5300 elements and it takes forever to render all those elements.

dawood11
  • 93
  • 2
  • 2
  • 6

4 Answers4

9

Yes you can. You need to add a scroll handler and test the scrollTop of the list vs the scrollHeight. Please add some code to your questions next time this way it will be easier for people to help you.

function LongList(props) {
  function loadMoreItems(event) {
    if (event.target.scrollTop === event.target.scrollHeight) {
     //user is at the end of the list so load more items
    } 
  }


  return (
    <List
      onScroll={loadMoreItems}
      style={{
        maxHeight:300,
        overflowY:'scroll'
      }}
    >
      <ListItem></ListItem>
      <ListItem></ListItem>
      <ListItem></ListItem>
      <ListItem></ListItem>
   </List>
  )
}

Edit: to target the list of a <Select> you need to target the <Menu> component composing the list of the select using the MenuProps prop.

<Select
  MenuProps={{
    PaperProps: {
      onScroll:loadMoreItems
    }
  }}
>
  {...menuItems}
</Select>

The way to target inner components in material-ui is described in their api approach documentation.

Duc Vo
  • 433
  • 3
  • 6
Anwardo
  • 650
  • 5
  • 15
  • how about the select list? – dawood11 Mar 21 '19 at 14:07
  • I editted my answer with a way to do it with a ` – Anwardo Mar 22 '19 at 22:55
  • I used the above code for the Select, but using event.target.scrollTop === event.target.scrollHeight did not work for me. To determine if the user had hit the bottom of the scroll options, I had to use `Math.abs(event.target.scrollHeight - event.target.clientHeight - event.target.scrollTop) < 1` – L Becker Mar 10 '22 at 16:45
  • If you use the first option with the onScroll method, double check if apart from the component height you don't have padding too, if you do, you need to add them to that if condition like. `event.target.scrollTop+COMPONENT_HEIGHT + COMPONENT_PADDING === event.target.scrollHeight` – Pedro Silva Jul 07 '22 at 21:19
1

Notice there response correct is use MenuProps, with Mayus:

<Select
  MenuProps={{
    onScroll:loadMoreItems
  }}
>
  {...menuItems}
</Select>
Divait
  • 11
  • 2
1

pay attention the height value plus event.target.scrollTop equals event.target.scrollHeight.

 const HeightPanel=300;
    
       function LongList(props) {
      function loadMoreItems(event) {
        if (event.target.scrollTop+HeightPanel === event.target.scrollHeight) {
         //user is at the end of the list so load more items
        } 
      }
    
    
      return (
        <List
          onScroll={loadMoreItems}
          style={{
            maxHeight:HeightPanel,
            overflowY:'scroll'
          }}
        >
          <ListItem></ListItem>
          <ListItem></ListItem>
          <ListItem></ListItem>
          <ListItem></ListItem>
       </List>
      )
    }

answer from Anwardo

Samira
  • 2,361
  • 1
  • 12
  • 21
1

For a select list you can do it like this:

  const loadMoreItems = (e) => {
     const bottom = e.target.scrollHeight === e.target.scrollTop + e.target.clientHeight;
       if(bottom){
         // add your code here
       }
   };
   
            <Select
              labelId="selectList"
              id="list"
              value={value}
              onChange={handleChange}
              MenuProps={{
                 PaperProps: {
                   onScroll: loadMoreItems,
                 },
                 style: {
                   maxHeight: 500,
                 },
              }}
              input={<Input />}
            >
               <MenuItem></MenuItem>
               <MenuItem></MenuItem>
          </Select>

 
sakshya73
  • 5,570
  • 5
  • 22
  • 41