diff --git a/packages/gatsby-react-router-scroll/src/scroll-container.tsx b/packages/gatsby-react-router-scroll/src/scroll-container.tsx index aafc994061b23..6ec1c5116aa6f 100644 --- a/packages/gatsby-react-router-scroll/src/scroll-container.tsx +++ b/packages/gatsby-react-router-scroll/src/scroll-container.tsx @@ -12,27 +12,28 @@ const propTypes = { children: PropTypes.element.isRequired, } -type Props = { +interface IProps { scrollKey: string shouldUpdateScroll?: Function children: React.ReactNode } -type PropsWithContextAndLocation = Props & { +interface IPropsWithContextAndLocation extends IProps { context: SessionStorage location: HLocation } class ScrollContainerImplementation extends React.Component< - PropsWithContextAndLocation + IPropsWithContextAndLocation > { - componentDidMount() { + componentDidMount(): void { + // eslint-disable-next-line react/no-find-dom-node const node = ReactDOM.findDOMNode(this) as Element const { location, scrollKey } = this.props if (!node) return - node.addEventListener("scroll", () => { + node.addEventListener(`scroll`, () => { this.props.context.save(location, scrollKey, node.scrollTop) }) @@ -40,22 +41,24 @@ class ScrollContainerImplementation extends React.Component< node.scrollTo(0, position) } - render() { + render(): React.ReactNode { return this.props.children } } -export const ScrollContainer = (props: Props) => ( +export const ScrollContainer = (props: IProps): React.ReactNode => ( - {({ location }) => ( + {({ location }): React.ReactNode => ( - {context => ( - - )} + {(context): React.ReactNode => { + return ( + + ) + }} )} diff --git a/packages/gatsby-react-router-scroll/src/scroll-handler.tsx b/packages/gatsby-react-router-scroll/src/scroll-handler.tsx index 62fe88b3d62b2..54bf3caa84e64 100644 --- a/packages/gatsby-react-router-scroll/src/scroll-handler.tsx +++ b/packages/gatsby-react-router-scroll/src/scroll-handler.tsx @@ -25,13 +25,15 @@ export class ScrollHandler extends React.Component< _stateStorage: SessionStorage = new SessionStorage() - scrollListener = () => { + scrollListener = (): void => { const { key } = this.props.location - this._stateStorage.save(this.props.location, key, window.scrollY) + if (key) { + this._stateStorage.save(this.props.location, key, window.scrollY) + } } - componentDidMount() { + componentDidMount(): void { window.addEventListener(`scroll`, this.scrollListener) const scrollPosition = this._stateStorage.read( @@ -45,17 +47,18 @@ export class ScrollHandler extends React.Component< } } - componentWillUnmount() { + componentWillUnmount(): void { window.removeEventListener(`scroll`, this.scrollListener) } componentDidUpdate(prevProps: LocationContext): void { - const { hash } = this.props.location + const { hash, key } = this.props.location + let scrollPosition + + if (key) { + scrollPosition = this._stateStorage.read(this.props.location, key) + } - const scrollPosition = this._stateStorage.read( - this.props.location, - this.props.location.key - ) if (scrollPosition) { this.windowScroll(scrollPosition, prevProps) } else if (hash) { @@ -96,7 +99,7 @@ export class ScrollHandler extends React.Component< return shouldUpdateScroll.call(this, prevRouterProps, routerProps) } - render() { + render(): React.ReactNode { return ( {this.props.children} diff --git a/packages/gatsby-react-router-scroll/src/session-storage.ts b/packages/gatsby-react-router-scroll/src/session-storage.ts index d03675e0d520c..74cbcdffc53bf 100644 --- a/packages/gatsby-react-router-scroll/src/session-storage.ts +++ b/packages/gatsby-react-router-scroll/src/session-storage.ts @@ -28,7 +28,7 @@ export class SessionStorage { } } - save(location: Location, key: string, value: number) { + save(location: Location, key: string, value: number): void { const stateKey = this.getStateKey(location, key) const storedValue = JSON.stringify(value) @@ -50,7 +50,7 @@ export class SessionStorage { } } - getStateKey(location: Location, key: string) { + getStateKey(location: Location, key: string): string { const locationKey = location.key || location.pathname const stateKeyBase = `${STATE_KEY_PREFIX}${locationKey}` return key === null || typeof key === `undefined` diff --git a/packages/gatsby-react-router-scroll/src/use-scroll-restoration.ts b/packages/gatsby-react-router-scroll/src/use-scroll-restoration.ts index 8b3430eb02803..1303ccb7937d0 100644 --- a/packages/gatsby-react-router-scroll/src/use-scroll-restoration.ts +++ b/packages/gatsby-react-router-scroll/src/use-scroll-restoration.ts @@ -2,20 +2,31 @@ import { ScrollContext } from "./scroll-handler" import { useRef, useContext, useLayoutEffect } from "react" import { useLocation } from "@reach/router" -export function useScrollRestoration(identifier: string) { +interface IScrollRestorationProps { + ref: React.MutableRefObject + onScroll(): void +} + +export function useScrollRestoration( + identifier: string +): IScrollRestorationProps { const location = useLocation() const state = useContext(ScrollContext) const ref = useRef() - useLayoutEffect(() => { - const position = state.read(location, identifier) - ref.current!.scrollTo(0, position) + useLayoutEffect((): void => { + if (ref.current) { + const position = state.read(location, identifier) + ref.current.scrollTo(0, position) + } }, []) return { ref, - onScroll() { - state.save(location, identifier, ref.current!.scrollTop) + onScroll(): void { + if (ref.current) { + state.save(location, identifier, ref.current.scrollTop) + } }, } }