withRouter.js 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import React from "react";
  2. import PropTypes from "prop-types";
  3. import hoistStatics from "hoist-non-react-statics";
  4. import invariant from "tiny-invariant";
  5. import RouterContext from "./RouterContext.js";
  6. /**
  7. * A public higher-order component to access the imperative API
  8. */
  9. function withRouter(Component) {
  10. const displayName = `withRouter(${Component.displayName || Component.name})`;
  11. const C = props => {
  12. const { wrappedComponentRef, ...remainingProps } = props;
  13. return (
  14. <RouterContext.Consumer>
  15. {context => {
  16. invariant(
  17. context,
  18. `You should not use <${displayName} /> outside a <Router>`
  19. );
  20. return (
  21. <Component
  22. {...remainingProps}
  23. {...context}
  24. ref={wrappedComponentRef}
  25. />
  26. );
  27. }}
  28. </RouterContext.Consumer>
  29. );
  30. };
  31. C.displayName = displayName;
  32. C.WrappedComponent = Component;
  33. if (__DEV__) {
  34. C.propTypes = {
  35. wrappedComponentRef: PropTypes.oneOfType([
  36. PropTypes.string,
  37. PropTypes.func,
  38. PropTypes.object
  39. ])
  40. };
  41. }
  42. return hoistStatics(C, Component);
  43. }
  44. export default withRouter;