1

I'm working on a project that is using react added into a static HTML page, but I can't get react router to work properly. I keep getting the following error from HashRouter:

index.tsx:177 Uncaught TypeError: Cannot read properties of undefined (reading 'createHashHistory')

Here are the CDN links I'm using for my project:

<script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js" crossorigin></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/6.2.1/react-router.development.js" integrity="sha512-x/vwJ8OCwhBaXS1SCWX2WiYvvIO6RKbMMn/ZlRP4CPhpM7SnaladKEnQgcejrA7Ep0RDMaxjB98VvOOlDuhm9Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/6.2.1/react-router-dom.development.js" integrity="sha512-uAx4/XQlub/EIs2IQ1Tq/kgkJF+GRNTocKZBDSSTSBjCZmfkvCUIQ+D9QoWlXXvgEkBCbGAaj7Ay+o/3EM9uuA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/history/5.2.0/history.development.js" integrity="sha512-He5zdxgskQISMuGJzMzSF7ndvQ2L9ffBpA9tkBIJwTTFnp2bBUVhND8JLvbLxGcLa5ul7wB/VijK7Lw4gkWMjA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

My router imports in my App component:

// Router
const Router = ReactRouterDOM.HashRouter;
const { createHashHistory } = history;
const Route = ReactRouterDOM.Route;
const Link = ReactRouterDOM.Link;

Router wrapped around my component:

<Router history={createHashHistory}>
  <MyAccount customerInfo={customerInfo}/>
</Router>

EDIT: Additional info about the HashRouter exception:

Seems to crash on this line: historyRef.current = createHashHistory({ window });

export function HashRouter({ basename, children, window }: HashRouterProps) {
  let historyRef = React.useRef<HashHistory>();
  if (historyRef.current == null) {
    historyRef.current = createHashHistory({ window });
  }

Any help is greatly appreciated, I can't find much info on getting this type of setup to work.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
boostedd
  • 268
  • 1
  • 3
  • 13
  • 1
    I'm looking into the history CDN part, but otherwise I don't think this will quite this simply. The higher-level routers exported in `react-router-dom` v6 don't take a `history` object as a prop. See [HashRouter](https://reactrouter.com/docs/en/v6/api#hashrouter). You'll need to create a custom router using the low-level [`Router`](https://reactrouter.com/docs/en/v6/api#router) first. It could just be that you need to reference a `History` instead of `history`, i.e. something like `const { createHashHistory } = History;` or `const createHashHistory = History.createHashHistory;`. – Drew Reese Dec 29 '21 at 17:04
  • I get the same exception when changing 'history' to 'History', and when I remove the history prop from my HashRouter I still get the error as well. I have added some more info about the exception above. – boostedd Dec 29 '21 at 17:13
  • 1
    Ok, looks like latest available for you on cdnjs is v5.1.0 (https://github.com/cdnjs/cdnjs/tree/master/ajax/libs/history). Try switching to ``. – Drew Reese Dec 29 '21 at 17:22

1 Answers1

1

Ok, looks like latest available for you on cdnjs is v5.1.0 (https://github.com/cdnjs/cdnjs/tree/master/ajax/libs/history).

Try switching to v5.1.0 from v5.2.0:

<script src="https://cdnjs.cloudflare.com/ajax/libs/history/5.1.0/history.development.js" integrity="sha512-..." ...></script>

To address my first comment regarding the router see my answer here for creating a custom hash router.

// Router
const Router = ReactRouterDOM.Router; // <-- low-level router!!
const { createHashHistory } = history;
const Route = ReactRouterDOM.Route;
const Link = ReactRouterDOM.Link;

const CustomRouter = ({ history, ...props }) => {
  const [state, setState] = useState({
    action: history.action,
    location: history.location
  });

  useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      {...props}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
};

...

const history = createHashHistory();

...

<CustomRouter history={createHashHistory}>
  <MyAccount customerInfo={customerInfo}/>
</CustomRouter>
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • This looks promising, but i'm getting `Uncaught TypeError: Cannot read properties of undefined (reading 'createHashHistory')` history.createHashHistory doesn't seem to exist. Actually, in the debugger `const { createHashHistory } = history;` history is undefined. – boostedd Dec 29 '21 at 17:54
  • @boostedd And if you try `History` here now, does it resolve the undefined issue? – Drew Reese Dec 29 '21 at 18:02
  • That did not work, however I did find that this references the correct function: `const { createHashHistory } = window.HistoryLibrary;` I am using and I also tried the CDN link you posted with the same results. I'm getting the same exact exception as the original post. – boostedd Dec 29 '21 at 18:07
  • Here is the value of `const history = createHashHistory();` ` { "action": "POP", "location": { "pathname": "/", "search": "", "hash": "", "state": null, "key": "default" } }` – boostedd Dec 29 '21 at 18:13
  • Thank you for the help! I changed out my CDN links to use react-router-dom v5.2.1 instead and everything is working now, the browser is showing the hashrouter behavior. The component wrapped in the router is not rendering, but that is a different issue since the rest of the applications components outside the router load fine. – boostedd Dec 29 '21 at 18:33
  • 1
    @boostedd Great! Are you saying that your `MyAccount` component specifically isn't rendering? I updated my answer to indicate you should import/use the low-level base `Router` component for the custom router since you are using a custom history object. Oh, just caught what you said about switching to RRDv5, yeah, the `HashRouter` from that version should work with a `history` prop. Can you still clarify the rendering issue? – Drew Reese Dec 29 '21 at 18:40
  • That is correct, `MyAccount` is rendering now with ` ` `const { createHashHistory } = window.HistoryLibrary;` was key since it wasn't referencing the module correctly. I am using your custom router still. – boostedd Dec 29 '21 at 18:44