bier hier bier hier - 8 months ago 81
React JSX Question

How can I set the proper scroll position my reactcomponent?

I developed a scroll component which renders 20 records at the time out of a total of 7000. What property can I use to position the scroll properly? There are 7000 rows so the scroll should move down 'slow' because there are a lot of rows.

Reactjs component:

import React, {Component} from 'react';

class Scroll extends Component {

constructor(props) {
super();
this.props = props;
this.state = {position: 0, pageSize: 20, displayedNames: this.props.names.slice(0, 20)}
}

onScroll = (event) => {
if (event.nativeEvent.wheelDelta > 0) {
console.log('scrollup');

if (this.state.position >= this.state.pageSize) {
this.setState({position: this.state.position - this.state.pageSize},
() => {
console.log('this.state.position=', this.state.position);
this.setState({displayedNames: this.props.names.slice(this.state.position, this.state.position + this.state.pageSize)});
});
}

} else {
console.log('scroll down');
if (this.state.position <= 7000) {
this.setState({position: this.state.position + this.state.pageSize},
() => {
console.log('this.state.position=', this.state.position);
this.setState({displayedNames: this.props.names.slice(this.state.position, this.state.position + this.state.pageSize)});
});
}

}

}

render() {
let display = this.state.displayedNames.map
(
(name) =>
{
if (name !=='')
{
return <div>{name}</div>
}
}



)

return (
<div id='container' onWheel={this.onScroll}>
<div className="scroll">
{display}
</div>
</div>
);
}
}


export default Scroll;


css:

#container{
height: 350px;
width:350px;
overflow-y: scroll;
border: 1px solid black;
}

Answer Source

If you want smooth scroll steps, you should jump one item back or forward. Why not use the onScroll event?

I have re-created your example and removed stuff from state. The only state information that the Scroll needs to maintain is the position. You can use Math.min and Math.max to avoid the position goes out of the allowed range.

Notice that the App provides the configuration and data, here I set scrollStep to be 1

App.js

import React from 'react';
import Scroll from './Scroll';

const App = props => {
  let names = [];
  for (let i = 1; i <= 7000; i++) {
    names.push('stackoverflow ' + i);
  }

  return (
    <div className="app">
      <Scroll names={names} displayItems={20} scrollStep={1} />
    </div>
  );
};

Scroll.js

import React from 'react';

export default 
class Scroll extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      position: 0
    };
  }

  onScroll = event => {

    const {scrollStep, names, displayItems} = this.props;

    if (event.nativeEvent.wheelDelta > 0) {
      console.log('scrollup');        

      this.setState({ 
          position: Math.max(
            this.state.position - scrollStep, 0)
        });
    } else {
      console.log('scroll down');

      this.setState({ 
        position: Math.min(
          this.state.position + scrollStep, names.length - displayItems) 
      });
    }
  };

  render() {

    let displayedNames = this.props.names.slice(
      this.state.position,
      this.state.position + this.props.displayItems
    );

    console.log('this.state.position:', this.state.position);

    return (
      <div className='container' id="container" onScroll={this.onScroll}>
        <div className="scroll">{displayedNames.map(
          (name, index) => <div key={index}>{name}</div>)}
        </div>
      </div>
    );
  }
}

Edit

If you are thinking about adjusting the scrollbar thumb size, then you can apply calculated padding values to the scroll element. (there might be some setting height trick using css). The browser auto-renders the scrollbar based on the DOM-content. The browser does not know you have 7000 items. It only knows you have displayItems which is 20 items. You can ensure it looks like it has 7000 items by applying padding values in top or bottom from the scroll element.

Edit 2

I have re-created a better example where the scrollbar is use-able, it can be seen here https://codepen.io/kunukn/full/JOZybL/

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download