Search code examples
reactjsreact-reduxreact-routerionic4ionic-react

Reducer not working properly inside IonRouterOutlet


This is the main component of my Ionic4 app ("PrivateRoute" component is from react-router-private):

const App: React.FC = (props: any) => {

    const { userLogged } = props.logged;

    return (
        <IonApp>
            <IonReactRouter>
                <IonRouterOutlet id="principal">
                    <Route exact path="/" render={() => <Redirect to="/login" />} />
                    <Route exact path="/login" component={LoginPage} />
                    <PrivateRoute exact path="/dashboard" component={Dashboard} authStatus={userLogged.isLogged} redirectURL="/login" />
                </IonRouterOutlet>
            </IonReactRouter>
            />
    </IonApp>
    );
}

const mapStateToProps = (state: any) => {
    return {
        logged: state.logged,
    };
}

export default connect(mapStateToProps)(App);

and this is my LoginPage component:

const LoginPage: React.FC = (props: any) => {

    const { userLogged } = props.logged;

    const handleLogin = (inputs: any) => {
        const user = {
            "username": inputs.username,
            "password": inputs.password,
        };

        axios.post(`URL`,
            user,
        )
            .then(response => {
                props.setLogged(response.data);
            })
            .catch(error => {});
    }

    return (
        <>{userLogged.isLogged ?
            <Redirect to="/dashboard" />
            :
            <IonPage>
                <IonContent>
                    <>
                        <IonGrid>
                            <IonRow>
                                <IonCol
                                    offsetXl="3" sizeXl="6"
                                    offsetLg="2" sizeLg="8"
                                    offsetMd="2" sizeMd="8"
                                    offsetSm="1" sizeSm="10"
                                    sizeXs="12">
                                    <Login save={handleLogin} >
                                    </Login>
                                </IonCol>
                            </IonRow>
                        </IonGrid>
                    </>
                </IonContent>
            </IonPage>
        }
        </>
    );
};

const mapStateToProps = (state: any) => {
    return {
        logged: state.logged,
    };
}

const mapDispatchToProps = {
    setLogged,
};

export default connect(mapStateToProps, mapDispatchToProps)(LoginPage);

The Login component inside LoginPage, is only a form and it is not necessary to go into details of it. The "setLogged" action only saves a JSON with user data and a session token, and changes the "isLogged" variable from the reducer to "true". This action is working properly.

The problem I have is the following. When the user logs in, the "LoginPage" component correctly detects the status variable "userLogged.isLogged" changes to "true", so it renders the <Redirect> to the "Dashboard" component, but the protected path of the component "Dashboard" does not detect it (at least it seems so). If I place the protected route outside the "IonRouterOutlet" it works perfect. But I need it to be inside the "IonRouterOutlet" because I need to access an event of the Ionic pages (useIonViewDidEnter). How can i fix this? Either by operating the protected route correctly from within the "IonRouterOutlet", or somehow simulating the "useIonViewDidEnter".

I already tried the following protected routes:

           <Route exact path="/dashboard"
                component={userLogged.isLogged ? Dashboard : LoginPage}
            />
            <Route exact path="/dashboard"
                render={props => {
                    return userLogged.isLogged ? <Dashboard {...props} /> : <LoginPage />;
                }}
            />

Thanks in advance


Solution

  • There was a bug fixed in one of the most recent versions that refreshed the closures created for the routes. After upgrading @ionic/react and @ionic/react-router to version 4.11.8, I can confirm that the bug is fixed. Also have to update @types/react to 16.9.19, and @types/react-router to 5.1.4, to avoid issues like this