0

I have a simple list of items.

      <List>
        {this.state.initialList.map((item, index) => (
          <ListItem key={index} button>
            <ListItemText primary={item} />
          </ListItem>
        ))}
      </List>

If I scroll to the bottom of the list and load a new list, the scroll stays at the bottom. How do I scroll back to the top of the list?

https://codesandbox.io/s/material-demo-l4i3s

In this sandbox, scroll to the bottom, click on "load", the list is showing the last item of the new list.

2 Answers 2

1

Not sure if there's a default setting you can set with material-ui to do this. But you definitely can apply some React functionality to get this to work.

See working sandbox: https://codesandbox.io/s/material-demo-8ftqz

Create a ref which would point to the top of the list:

  topOfList = React.createRef();

Then in your List Component, return a span at the top of the list. Give that span the ref you crated.

      <List component="nav" aria-label="secondary mailbox folders">
        {<span ref={this.topOfList} />}
        {this.state.initialList.map((item, index) => (
          <ListItem key={index} button>
            <ListItemText primary={item} />
          </ListItem>
        ))}
      </List>

Create an additional handler that scrolls to the element/ref:

  scrollToTop = () => {
    if (this.topOfList.current) {
      this.topOfList.current.scrollIntoView();
    }
  };

Lastly, use the handler inside the set-state call-back to ensure you scroll-up after the data has loaded.

this.setState({ initialList: newList }, () => this.scrollToTop())
Sign up to request clarification or add additional context in comments.

1 Comment

I'm not too found of scrollIntoView. I already have an annoying bug in Firefox with it.
1

The scroll is caused by the parent div.
You can hold a ref to that div, and on load, use the function scorllTo() to position the scrollbar to the top.

 <div ref={ref => this.divRef = ref} class="mylist">
          <List component="nav" aria-label="secondary mailbox folders">
            {this.state.initialList.map((item, index) => (
              <ListItem key={index} button>
                <ListItemText primary={item} />
              </ListItem>
            ))}
          </List>
 </div>

and than in load function:

  load = () => {
    const newList = [
      "new1",
      "new2",
      "new3",
      "new4",
      "new5",
      "new6",
      "new7",
      "new8",
      "new9",
      "new0"
    ];
    this.divRef.scrollTo(0,0);
    this.setState({ initialList: newList });
  };

You can refer to this CodeSandbox example

2 Comments

You forgot to modify the sandbox?
@gyc yes, sorry. I updated the answer with the right link

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.