react-router-scroll-internal-history
v0.0.1
Published
React Router scroll management, without a history peerDependency
Downloads
2
Maintainers
Readme
react-router-scroll
React Router scroll management.
fork: react-router-scroll-internal-history
I was looking to use react-router-scroll, for an existing work project, but could not because it already uses history @^4.5.1
. This means react-router-scroll:
- generates an
unmet peer dependency
warning duringnpm install
- will not install a compatible version of
history
for itself - fails at runtime as
history@^4.0.0
is incompatible
As the history
module is only used to retrieve information react-router-scroll
has explicitly stored, it does not need to be the same version of history
that the rest of the app uses. Therefore, it should be able to be specified as a standard dependency!
react-router-scroll-internal-history
uses history@^2.1.2
internally, leaving your app free to use whatever history
version it likes*
*only tested in anger with the following
package.json
dependencies: history@^4.5.1, react-router@^3.0.1, react-dom@^15.4.2, react@^15.4.2
react-router-scroll is a React Router middleware that adds scroll management using scroll-behavior. By default, the middleware adds browser-style scroll behavior, but you can customize it to scroll however you want on route transitions.
This library does not currently support React Router v4, because React Router v4 has no concept of router middlewares. See ongoing discussion in #52. For an interim solution for just scrolling to top on navigation, see the React Router documentation on scroll restoration.
Usage
import { applyRouterMiddleware, browserHistory, Router } from 'react-router';
import { useScroll } from 'react-router-scroll';
/* ... */
ReactDOM.render(
<Router
history={browserHistory}
routes={routes}
render={applyRouterMiddleware(useScroll())}
/>,
container
);
Guide
Installation
$ npm i -S react react-dom react-router
$ npm i -S react-router-scroll
Basic usage
Apply the useScroll
router middleware using applyRouterMiddleware
, as in the example above.
Custom scroll behavior
You can provide a custom shouldUpdateScroll
callback as an argument to useScroll
. This callback is called with the previous and the current router props.
The callback can return:
- a falsy value to suppress updating the scroll position
- a position array of
x
andy
, such as[0, 100]
, to scroll to that position - a string with the
id
orname
of an element, to scroll to that element - a truthy value to emulate the browser default scroll behavior
useScroll((prevRouterProps, { location }) => (
prevRouterProps && location.pathname !== prevRouterProps.location.pathname
));
useScroll((prevRouterProps, { routes }) => {
if (routes.some(route => route.ignoreScrollBehavior)) {
return false;
}
if (routes.some(route => route.scrollToTop)) {
return [0, 0];
}
return true;
});
Scrolling elements other than window
Use <ScrollContainer>
in components rendered by a router with the useScroll
middleware to manage the scroll behavior of elements other than window
. Each <ScrollContainer>
must be given a unique scrollKey
, and can be given an optional shouldUpdateScroll
callback that behaves as above.
import { ScrollContainer } from 'react-router-scroll';
function Page() {
/* ... */
return (
<ScrollContainer
scrollKey={scrollKey}
shouldUpdateScroll={shouldUpdateScroll}
>
<MyScrollableComponent />
</ScrollContainer>
);
}
<ScrollContainer>
does not support on-the-fly changes to scrollKey
or to the DOM node for its child.
Notes
Minimizing bundle size
If you are not using <ScrollContainer>
, you can reduce your bundle size by importing the useScroll
module directly.
import useScroll from 'react-router-scroll/lib/useScroll';
Server rendering
Do not apply the useScroll
middleware when rendering on a server. You may use <ScrollContainer>
in server-rendered components; it will do nothing when rendering on a server.