IONIC 4 [React]: passing history props to IonReactRouter doesn't work as expected

I have a separate history.ts file.

// history.js
import { createBrowserHistory } from 'history';

export default createBrowserHistory({
    /* pass a configuration object here if needed */
})

I want to pass history to IonReactRouter like this -

import createBrowserHistory from './history';
const App: React.FC = () => (
    <IonApp>
        <IonReactRouter history={createBrowserHistory}>
            <IonRouterOutlet>
                <Route path="/home" component={Home} exact={true}/>
               .....
                <Route exact path="/" render={() => <Redirect to="/home"/>}/>
            </IonRouterOutlet>
        </IonReactRouter>
    </IonApp>
);

The reason is that I want to use history.goBack() outside of the component. While trying to handle the hardware back button with capacitor, if backButton event is written inside the component, it fires multiple times and goes back to the first page. Also, location.pathname stays the same.

Now, if I pass history to IonReactRouter, tslint shows this error -

TS2769: No overload matches this call
Overload 1 af 2 . ’ ( props : Readonly ) : IonReactRouter ’ gave the following error.
Type {children : Element ; history . History; }’ Is not assignable to type ‘IntrinsicAttributes & IntrinsicClassAttributes & Readonly & Readonly <{children: ReactNode; } >’ . Property ’ history does not exist on type ’ intrinsicAttributes & IntrinsicclassAttributes & Readonly & Readonly {children : ReactNode ;}> .
Overload 2 of 2 , ’ ( props : Browser RouterProps , context ? : any ) : IonReactRouter ’ gave the following error.
Type ’ children : Element ; history . History : ) is not assignable to type ’ IntrinsicAttributes & IntrinsicClassAttributes & Readonly & Readonly <{children : ReactNode ;}>'.
Property ’ history does not exist on type ’ IntrinsicAttributes & IntrinsicClassAttributesc & Readonly & Readonly <{children: ReactNode ;}> ’

I am ignoring it by adding @ts-ignore but that doesn’t feel like a reliable way. Also, according to the official doc, it should be allowed.

The IonReactRouter component wraps the traditional BrowserRouter component from React Router, and sets the app up for routing. Therefore, use IonReactRouter in place of BrowserRouter . You can pass in any props to IonReactRouter and they will be passed down to the underlying BrowserRouter.

With @ts-ignore, and adding the event listener outside of the component, it’s firing once and going back to one page as expected. I don’t want it to go back while on Home page but on rare occasions, it is misbehaving and keeps going back. I couldn’t pinpoint how and when this happens.

import history from '../history';

import {Plugins} from "@capacitor/core";

const {App} = Plugins;

App.addListener('backButton', () => {
    if(history.location.pathname !== '/home'){
        console.log(history);
        history.goBack();
    }
});

const Home: React.FC = () => {
......................
......................

The value of location.pathname is always ‘/’ and doesn’t change. Also, the page transition animation is wrong and it looks like it pushes the page instead of pop.

3 Likes

What’s wrong with the withRouter() HOC from react for getting a history prop?

4 Likes