From 755caea96f19439f06ceba71cf2396a8d319effc Mon Sep 17 00:00:00 2001 From: Haoliang Wu Date: Thu, 30 Jan 2020 21:08:51 +0800 Subject: [PATCH] feat: add onSync callback to resolve #87 (#91) * feat: add onSync callback to resolve #87 * fix: should keep updateScroll as manual trigger api * doc: update the README * simplify code Co-authored-by: Allen Yang --- README.md | 7 +++++ example/example.js | 65 +++++++++++++++++++++++++++++++++------------- src/scrollbar.js | 9 +++++-- 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 5dcca91..b8cc4c1 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,13 @@ All the callback 'onXXXX' can accept a parameter: the ref to the scrollbar conta ``` +#### onSync +Invoked when `PerfectScrollbar` comp needs to sync the scrollbar container by invoking `ps.update()`(Basically, it is invoked in CDU lifecycle) and receive the internal `perfect-scroll` instance `ps` as parameter. + +It is useful when you want to customize the sync logic in some scenarios, eg: debounce the invocation of `ps.update()`. + +For more detail, please refer to [issue#87](https://github.com/goldenyz/react-perfect-scrollbar/issues/87) and the example directory. + #### React.HTMLAttributes Any attributes defined in [React.HTMLAttributes](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/index.d.ts#L1689) can be used for the component. diff --git a/example/example.js b/example/example.js index 7008eef..8a92ad9 100644 --- a/example/example.js +++ b/example/example.js @@ -10,6 +10,14 @@ function logEvent(type) { console.log(`event '${type}' triggered!`); } +const debounce = (fn, ms = 0) => { + let timeoutId; + return function wrapper(...args) { + clearTimeout(timeoutId); + timeoutId = setTimeout(() => fn.apply(this, args), ms); + }; +}; + class Example extends Component { constructor(props) { super(props); @@ -17,6 +25,7 @@ class Example extends Component { this.state = { className: undefined, onXReachEnd: null, + items: Array.from(new Array(100).keys()), }; } @@ -33,28 +42,48 @@ class Example extends Component { logEvent('onYReachEnd'); } + handleTrigger = () => { + this.setState({ + items: Array.from(new Array(100).keys()), + }); + } + + handleSync = debounce((ps) => { + ps.update(); + console.log('debounce sync ps container in 1000ms'); + }, 1000) + render() { const { className, onXReachEnd } = this.state; return ( -
- logEvent('onScrollY')} - onScrollX={() => logEvent('onScrollX')} - onScrollUp={() => logEvent('onScrollUp')} - onScrollDown={() => logEvent('onScrollDown')} - onScrollLeft={() => logEvent('onScrollLeft')} - onScrollRight={() => logEvent('onScrollRight')} - onYReachStart={() => logEvent('onYReachStart')} - onYReachEnd={this.handleYReachEnd} - onXReachStart={() => logEvent('onXReachStart')} - onXReachEnd={onXReachEnd} - component="div" - > -
- -
+ + +
+ logEvent('onScrollY')} + onScrollX={() => logEvent('onScrollX')} + onScrollUp={() => logEvent('onScrollUp')} + onScrollDown={() => logEvent('onScrollDown')} + onScrollLeft={() => logEvent('onScrollLeft')} + onScrollRight={() => logEvent('onScrollRight')} + onYReachStart={() => logEvent('onYReachStart')} + onYReachEnd={this.handleYReachEnd} + onXReachStart={() => logEvent('onXReachStart')} + onXReachEnd={onXReachEnd} + component="div" + > +
+ +
+
+ + + {this.state.items.map(e => (
{e}
))} +
+
+ ); } } diff --git a/src/scrollbar.js b/src/scrollbar.js index e8c8b94..b296d9f 100644 --- a/src/scrollbar.js +++ b/src/scrollbar.js @@ -37,7 +37,9 @@ export default class ScrollBar extends Component { componentDidUpdate(prevProps) { this._updateEventHook(prevProps); - this._ps.update(); + + this.updateScroll(); + if (prevProps.className !== this.props.className) { this._updateClassName(); } @@ -90,7 +92,7 @@ export default class ScrollBar extends Component { } updateScroll() { - this._ps.update(); + this.props.onSync(this._ps); } handleRef(ref) { @@ -116,6 +118,7 @@ export default class ScrollBar extends Component { onXReachStart, onXReachEnd, component, + onSync, children, ...remainProps } = this.props; @@ -145,6 +148,7 @@ ScrollBar.defaultProps = { onYReachEnd: undefined, onXReachStart: undefined, onXReachEnd: undefined, + onSync: ps => ps.update(), component: 'div', }; @@ -165,5 +169,6 @@ ScrollBar.propTypes = { onYReachEnd: PropTypes.func, onXReachStart: PropTypes.func, onXReachEnd: PropTypes.func, + onSync: PropTypes.func, component: PropTypes.string, };