ctrlplusb / react-sizeme

Make your React Components aware of their width and height!
MIT License
1.94k stars 94 forks source link

scrollTop is set to (offset) height when using SizeMe. #154

Open Izhaki opened 6 years ago

Izhaki commented 6 years ago

When using SizeMe, it leads to an onScroll event from the wrapped component with scrollTop set to the element height:

Example I (SizeMe wraps the scrolled component)

import React from 'react';
import sizeMe from 'react-sizeme';

const withSize = sizeMe({ monitorHeight: true, monitorWidth: false });

const withViewport = WrappedComponent => {
  class ViewPort extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        scrollTop: 0,
      };
    }

    render() {
      const { scrollTop } = this.state;
      console.log(scrollTop);
      return (
        <div
          onScroll={evt => this.setState({ scrollTop: evt.target.scrollTop })}
          style={{ overflowY: 'scroll', flex: 1 }}>
          <WrappedComponent {...this.props} scrollTop={scrollTop} />
        </div>
      );
    }
  }
  return withSize(ViewPort);
};

export default withViewport;

console:

0
0
10
527

That's incorrect, because the scrollTop is actually 0.

Note this note on scrollTop:

If set to a value greater than the maximum available for the element, scrollTop settles itself to the maximum value.

Example II (SizeMe is inside the scrolled component)

Also happens in this case:

import React from 'react';
import sizeMe from 'react-sizeme';

const withSize = sizeMe({ monitorHeight: true, monitorWidth: false });

const withHeight = WrappedComponent => {
  class WithHeight extends React.Component {
    render() {
      const { size, ...props } = this.props;
      return <WrappedComponent {...props} height={size.height} />;
    }
  }
  return withSize(WithHeight);
};

const withViewport = WrappedComponent => {
  const WrappedComponentWithHeight = withHeight(WrappedComponent);
  class ViewPort extends React.Component {
    constructor(props) {
      super(props);
      this.state = {
        scrollTop: 0,
      };
    }

    render() {
      const { scrollTop } = this.state;
      console.log(scrollTop);
      return (
        <div
          onScroll={evt => this.setState({ scrollTop: evt.target.scrollTop })}
          style={{ overflowY: 'scroll', flex: 1 }}>
          <WrappedComponentWithHeight {...this.props} scrollTop={scrollTop} />
        </div>
      );
    }
  }
  return withSize(ViewPort);
};

export default withViewport;
AdnanBoota commented 4 years ago

Any solution for the scroll Issue? i'm also having it.