React scroll component to view inside overflow hidden element

16,736

Solution 1

I'm going to give you a simple fix but this is how it works. You will need to set the overflow of the div containing all the elements to scroll. This is because if you set it to hidden all elements that are can't fit into that div get hidden. The solution I'm giving you doesn't require even using react-scroll-to-component or any package.

import React from "react";
import { render } from "react-dom";

class Item extends React.Component {
  render() {
    const { item } = this.props;
    return (
      <div style={{ padding: `12px` }} id={item}>
        Item {item}
      </div>
    );
  }
}

class List extends React.Component {
  state = {
    items: [
      1,
      2,
      3,
      4,
      5,
      6,
      7,
      8,
      9,
      10,
      11,
      12,
      13,
      14,
      15,
      16,
      17,
      18,
      19,
      20
    ]
  };


  onClick = () => {
    /** You can avoid using getElementById if you can get the div rendered by Item component using refs.
     * You can look at refs forwarding and other technics to see how you can solve this */
    const divToScrollTo = document.getElementById(`${this.ref_20.props.item}`);
    if (divToScrollTo) {
      divToScrollTo.scrollIntoView();
    }
  };

  render() {
    const { items } = this.state;
    return (
      <div>
        <h1>My List</h1>
        <button onClick={this.onClick}>Clickidy</button>
        <div
          style={{
            height: `200px`,
            overflow: "scroll",
            backgroundColor: "red"
          }}
        >
          {this.state.items.map(item => (
            <Item ref={inst => (this[`ref_${item}`] = inst)} item={item} />
          ))}
        </div>
      </div>
    );
  }
}

Or you can click the link below for the code pen solution https://codesandbox.io/s/2vo0j2w660

I haven't done more optimisations which are required in your code because I'm time bad but hope this helps

Its even easier if you used refs forwarding as shown at code pen here https://codesandbox.io/s/yjj66xl2v1 but you have to create refs in the constructor method`

Solution 2

Change line 55 from overflow: hidden to overflow: scroll.

Share:
16,736

Related videos on Youtube

Dennis
Author by

Dennis

Updated on June 04, 2022

Comments

  • Dennis
    Dennis almost 2 years

    I have a list which contains a series of items, but I can't get it to scroll another item into view. Solutions such as this doesn't quite work, because I have to scroll up and down (basically if the list is too large, scroll it at intervals to display all items).

    I made a codepen that illustrates the problem with react-scroll-to-component, but I am open to any library / native solution. The basic functionality is just scrollToComponent(ref, <options>).

    The error as far as I can tell is that it attempts to scroll on the body, rather than the actual container. If you remove the height / overflow properties of the div, it will work.

    Doesn't work:

    <div
        style={{
        height: `200px`,
        overflow: "hidden"
        }}
    >
        {this.state.items.map(item => (
        <Item ref={inst => (this[`ref_${item}`] = inst)} item={item} />
        ))}
    </div>
    

    Works:

    <div>
        {this.state.items.map(item => (
        <Item ref={inst => (this[`ref_${item}`] = inst)} item={item} />
        ))}
    </div>
    

    Full code for anyone not wanting to go to codepen:

    class Item extends React.Component {
      render() {
        return <div style={{ padding: `12px` }}>Item {this.props.item}</div>;
      }
    }
    
    class List extends React.Component {
      state = {
        items: [
          1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18,
          19,
          20
        ]
      };
    
      componendDidMount() {
        this.state.items.forEach(item => (this[`ref_${item}`] = React.createRef()));
      }
    
      onClick = () => {
        scrollToComponent(this.ref_20);
      };
    
      render() {
        const { items } = this.state;
        return (
          <div>
            <h1>My List</h1>
            <button onClick={this.onClick}>Clickidy</button>
            {/*Replace with <div> to see it work*/}
            <div
              style={{
                height: `200px`,
                overflow: "hidden",
                backgroundColor: "red"
              }}
            >
              {this.state.items.map(item => (
                <Item ref={inst => (this[`ref_${item}`] = inst)} item={item} />
              ))}
            </div>
          </div>
        );
      }
    }
    
  • MarcoS
    MarcoS almost 6 years
    It does not scroll even with overflow: scroll... Just tested on codepen
  • Dennis
    Dennis almost 6 years
    Worked like a charm. It seemed to be the ref'ing that was actually the problem child. overflow:scroll is not really needed. Thanks for the help and take my upvote!
  • Jjagwe Dennis
    Jjagwe Dennis almost 6 years
    Yeah, it's not but I assumed that maybe you needed a user to scroll over the list as well. The problem was with the way you were using and creating refs.
  • Kevin
    Kevin over 3 years