-
Notifications
You must be signed in to change notification settings - Fork 63
/
ScrollBehaviorContext.js
85 lines (66 loc) · 2.06 KB
/
ScrollBehaviorContext.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import PropTypes from 'prop-types';
import React from 'react';
import ScrollBehavior from 'scroll-behavior';
import StateStorage from './StateStorage';
const propTypes = {
shouldUpdateScroll: PropTypes.func,
routerProps: PropTypes.object.isRequired,
children: PropTypes.element.isRequired,
};
const childContextTypes = {
scrollBehavior: PropTypes.object.isRequired,
};
class ScrollBehaviorContext extends React.Component {
constructor(props, context) {
super(props, context);
const { routerProps } = props;
const { router } = routerProps;
this.scrollBehavior = new ScrollBehavior({
addTransitionHook: router.listenBefore,
stateStorage: new StateStorage(router),
getCurrentLocation: () => this.props.routerProps.location,
shouldUpdateScroll: this.shouldUpdateScroll,
});
this.scrollBehavior.updateScroll(null, routerProps);
}
getChildContext() {
return {
scrollBehavior: this,
};
}
componentDidUpdate(prevProps) {
const { routerProps } = this.props;
const prevRouterProps = prevProps.routerProps;
if (routerProps.location === prevRouterProps.location) {
return;
}
this.scrollBehavior.updateScroll(prevRouterProps, routerProps);
}
componentWillUnmount() {
this.scrollBehavior.stop();
}
shouldUpdateScroll = (prevRouterProps, routerProps) => {
const { shouldUpdateScroll } = this.props;
if (!shouldUpdateScroll) {
return true;
}
// Hack to allow accessing scrollBehavior._stateStorage.
return shouldUpdateScroll.call(
this.scrollBehavior, prevRouterProps, routerProps,
);
};
registerElement = (key, element, shouldUpdateScroll) => {
this.scrollBehavior.registerElement(
key, element, shouldUpdateScroll, this.props.routerProps,
);
};
unregisterElement = (key) => {
this.scrollBehavior.unregisterElement(key);
};
render() {
return this.props.children;
}
}
ScrollBehaviorContext.propTypes = propTypes;
ScrollBehaviorContext.childContextTypes = childContextTypes;
export default ScrollBehaviorContext;