react_router.tsx 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import PropTypes from 'prop-types';
  2. import { __RouterContext } from 'react-router';
  3. import hoistStatics from 'hoist-non-react-statics';
  4. export const WithRouterPropTypes = {
  5. match: PropTypes.object.isRequired,
  6. location: PropTypes.object.isRequired,
  7. history: PropTypes.object.isRequired,
  8. };
  9. export const WithOptionalRouterPropTypes = {
  10. match: PropTypes.object,
  11. location: PropTypes.object,
  12. history: PropTypes.object,
  13. };
  14. export interface OptionalRouterProps {
  15. ref: unknown;
  16. wrappedComponentRef: unknown;
  17. }
  18. // This is copied from https://github.com/remix-run/react-router/blob/v5.3.4/packages/react-router/modules/withRouter.js
  19. // but does not fail if called outside of a React Router context
  20. export function withOptionalRouter<
  21. ComponentType extends React.ComponentType<OptionalRouterProps>,
  22. >(Component: ComponentType) {
  23. const displayName = `withRouter(${Component.displayName ?? Component.name})`;
  24. const C = (props: React.ComponentProps<ComponentType>) => {
  25. const { wrappedComponentRef, ...remainingProps } = props;
  26. return (
  27. <__RouterContext.Consumer>
  28. {(context) => {
  29. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
  30. if (context) {
  31. return (
  32. // @ts-expect-error - Dynamic covariant generic components are tough to type.
  33. <Component
  34. {...remainingProps}
  35. {...context}
  36. ref={wrappedComponentRef}
  37. />
  38. );
  39. } else {
  40. // @ts-expect-error - Dynamic covariant generic components are tough to type.
  41. return <Component {...remainingProps} ref={wrappedComponentRef} />;
  42. }
  43. }}
  44. </__RouterContext.Consumer>
  45. );
  46. };
  47. C.displayName = displayName;
  48. C.WrappedComponent = Component;
  49. C.propTypes = {
  50. ...Component.propTypes,
  51. wrappedComponentRef: PropTypes.oneOfType([
  52. PropTypes.string,
  53. PropTypes.func,
  54. PropTypes.object,
  55. ]),
  56. };
  57. return hoistStatics(C, Component);
  58. }