Property 'history' does not exist on type 'IntrinsicAttributes
Asked Answered
F

2

11

I'm wrapping react app in Router with passing createBrowserHistory prop. But getting "property 'history' does not exist on type 'IntrinsicAttributes & RouterPops"

Here is my index.tsx

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { Router } from "react-router-dom";
import history from "../src/utils/history";

ReactDOM.render(
    <Router history={history}>
    <App />
  </Router>,
  document.getElementById("root")
);

Here is my history.tsx

import { createBrowserHistory } from "history";

const history = createBrowserHistory();

export default history;

I'm using react-router-dom v6.0.2

Feudist answered 12/11, 2021 at 19:27 Comment(4)
Router components no longer take a history object in v6.x. You should also instead now use one of the higher level routers, i.e. BrowserRouter, etc.Napoleon
Can you provide link for any article to overcome this problemFeudist
What are you trying to do with "history"? Does this answer help? https://mcmap.net/q/1158580/-react-router-dom-throws-two-errors-when-reading-the-pathname-propertyNapoleon
I'm using history in axios interceptor to redirect user to login page if he is not logged inFeudist
N
4

I suspect you could implement a bit more of the logic of one of the higher level routers and get the behavior you want with a custom history object.

BrowserRouter implementation for example:

export function BrowserRouter({
  basename,
  children,
  window
}: BrowserRouterProps) {
  let historyRef = React.useRef<BrowserHistory>();
  if (historyRef.current == null) {
    historyRef.current = createBrowserHistory({ window });
  }

  let history = historyRef.current;
  let [state, setState] = React.useState({
    action: history.action,
    location: history.location
  });

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

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

Create a CustomRouter that consumes a custom history object and manages the state:

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}
    />
  );
};

Edit property-history-does-not-exist-on-type-intrinsicattributes

Napoleon answered 12/11, 2021 at 20:0 Comment(0)
M
2

2023 Answer - React Typescript error: Property 'history' does not exist on type 'IntrinsicAttributes'

The exact typescript error I got was :

Type '{ children: Element; history: BrowserHistory; }' is not assignable to type 'IntrinsicAttributes & BrowserRouterProps'. Property 'history' does not exist on type 'IntrinsicAttributes & BrowserRouterProps'.

After hours of many research and troubleshooting the solution that resolves the issue is stated below.

Step 1 - install "history" into you project dependency

npm i history

Step 2 - import Router and createMemoryHistory from the correct sources

Importing BrowserRouter from "react-router-dom" is outdated, and also is importing {createBrowserHistory} from "history", so we need to import Router and createMemoryHistory as seen below...

import { BrowserRouter } from "react-router-dom";
import { createMemoryHistory } from "history";

Step 3 - define history from createMemoryHistory

const history = createMemoryHistory();

Step 4 - pass the history props to your Router

Finally you pass history={history} and navigator={history}, as seen below...

<Router history={history} navigator={history}>
 <React.StrictMode>
  <App />
 </React.StrictMode>
</Router>

Finally your entire "index.tsx" should look like the following...

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router-dom";
import { createMemoryHistory } from "history";
import "./index.css";
import App from "./App";
import * as serviceWorkerRegistration from "./serviceWorkerRegistration";
import reportWebVitals from "./reportWebVitals";

const history = createMemoryHistory();

const root = ReactDOM.createRoot(
    document.getElementById("root") as HTMLElement
);
root.render(
    <BrowserRouter history={history} navigator={history}>
        <React.StrictMode>
            <App />
        </React.StrictMode>
    </BrowserRouter>
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: 
serviceWorkerRegistration.register();

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: 
reportWebVitals();
Mimicry answered 13/2, 2023 at 9:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.