Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: React fallback route causes flicker transition when routing between pages #24855

Open
6 tasks done
ashishbairwa opened this issue Feb 28, 2022 · 12 comments
Open
6 tasks done
Labels
package: react @ionic/react package type: bug a confirmed bug report

Comments

@ashishbairwa
Copy link

ashishbairwa commented Feb 28, 2022

Prerequisites

Ionic Framework Version

  • v4.x
  • v5.x
  • v6.x

Current Behavior

Summary:

Navigating to a random page right after implementing a default or a guarded route or a fallback route (following the method suggested in docs also https://ionicframework.com/docs/react/navigation#fallback-route) and then moving back and forth in the app leads to flickering/black glitch. Reloading the same page seems to correct this issue.

Context:

Hey there, We decided to go with ionic react for our patient application and we are nearly done with that. While setting page boundaries. I’ve decided to redirect the user based on a context value and prevent from falling into any unmatched route.

Here is how I declared that:

return <QueryClientProvider client={queryClient}>

    <IonApp>

      <IonReactRouter>

        <IonSplitPane contentId="main">

          {isLoggedIn && <Menu />}

          <IonRouterOutlet id="main">

            <Route path="/home" render={() => isLoggedIn ? <Home /> : <Redirect to="/login" />} exact={true} />

            <Route path="/payment-history" render={() => isLoggedIn ? <PaymentHistory /> : <Redirect to="/login" />} exact={true} />

            <Route path="/renewal" render={() => isLoggedIn ? <Packages /> : <Redirect to="/login" />} exact={true} />

            <Route path="/session-result/:type" render={() => isLoggedIn ? <SessionResult /> : <Redirect to="/login" />} exact={true} />

            <Route path="/treatment-plan" render={() => isLoggedIn ? <TreatmentPlan /> : <Redirect to="/login" />} exact={true} />

            <Route path="/profile" render={() => isLoggedIn ? <Profile /> : <Redirect to="/login" />} exact={true} />

            <Route path="/cancellation-policy" render={() => isLoggedIn ? <CancellationPolicy /> : <Redirect to="/login" />} exact={true} />

            <Route path="/terms-and-conditions" render={() => isLoggedIn ? <TermsAndConditions /> : <Redirect to="/login" />} exact={true} />

            <Route path="/help" render={() => isLoggedIn ? <Help /> : <Redirect to="/login" />} exact={true} />

            <Route path="/notifications" render={() => isLoggedIn ? <Notifications /> : <Redirect to="/login" />} exact={true} />

            <Route path="/getting-started" render={() => isLoggedIn ? <GettingStarted /> : <Redirect to="/login" />} exact={true} />

            <Route path="/progress-report" render={() => isLoggedIn ? <Progress /> : <Redirect to="/login" />} exact={true} />

            <Route path="/policies" render={() => isLoggedIn ? <Policies /> : <Redirect to="/login" />} exact={true} />

            <Route path="/login" render={() => !isLoggedIn ? <Authentication /> : <Redirect to="/home" />} exact={true} />

            <Route render={() => !isLoggedIn ? <Redirect to={'/login'} /> : <Redirect to={'/home'} />} />

            {/* <Redirect to={ !isLoggedIn ? '/login' : '/home' } /> */}

            {/* { MountedRoutes } */}

          </IonRouterOutlet>

        </IonSplitPane>

      </IonReactRouter>

    </IonApp>

    { process.env.REACT_APP_ENV_STAGE === 'dev' && <ReactQueryDevtools initialIsOpen={false} />}

  </QueryClientProvider>;

Navigation is working fine but there is an issue with how it’s animating, it ended up giving strange flickering while moving from one page to other page. One thing which I observed is when I refresh the page, flickering goes away and everything works as expected.

Here is the package.json:

{

  "name": "patient-app",

  "version": "0.0.2",

  "private": true,

  "dependencies": {

    "@capacitor/android": "3.3.4",

    "@capacitor/app": "1.0.7",

    "@capacitor/clipboard": "^1.0.6",

    "@capacitor/core": "3.3.3",

    "@capacitor/haptics": "1.1.3",

    "@capacitor/keyboard": "1.2.0",

    "@capacitor/splash-screen": "^1.2.0",

    "@capacitor/status-bar": "^1.0.6",

    "@dotmind/react-use-pwa": "^1.0.4",

    "@frogress/line": "^1.1.0",

    "@ionic/react": "^6.0.0",

    "@ionic/react-router": "^6.0.0",

    "@testing-library/jest-dom": "^5.11.9",

    "@testing-library/react": "^11.2.5",

    "@testing-library/user-event": "^12.6.3",

    "@types/jest": "^26.0.20",

    "@types/node": "^12.19.15",

    "@types/react": "^16.14.3",

    "@types/react-dom": "^16.9.10",

    "@types/react-router": "^5.1.11",

    "@types/react-router-dom": "^5.1.7",

    "chart.js": "^3.7.0",

    "classnames": "^2.3.1",

    "contentful": "^9.1.6",

    "date-fns": "^2.28.0",

    "firebase": "^9.6.1",

    "framer-motion": "^4.1.17",

    "html-react-parser": "^1.4.5",

    "ionicons": "^5.4.0",

    "lodash": "^4.17.21",

    "react": "^17.0.1",

    "react-chartjs-2": "^4.0.0",

    "react-dom": "^17.0.1",

    "react-icons": "^4.3.1",

    "react-lines-ellipsis": "^0.15.0",

    "react-onesignal": "^2.0.2",

    "react-otp-input": "^2.4.0",

    "react-phone-input-2": "^2.14.0",

    "react-query": "^3.34.12",

    "react-router": "^5.2.0",

    "react-router-dom": "^5.2.0",

    "react-scripts": "4.0.2",

    "styled-components": "^5.3.3",

    "typescript": "^4.1.3",

    "web-vitals": "^0.2.4",

    "workbox-background-sync": "^5.1.4",

    "workbox-broadcast-update": "^5.1.4",

    "workbox-cacheable-response": "^5.1.4",

    "workbox-core": "^5.1.4",

    "workbox-expiration": "^5.1.4",

    "workbox-google-analytics": "^5.1.4",

    "workbox-navigation-preload": "^5.1.4",

    "workbox-precaching": "^5.1.4",

    "workbox-range-requests": "^5.1.4",

    "workbox-routing": "^5.1.4",

    "workbox-strategies": "^5.1.4",

    "workbox-streams": "^5.1.4"

  }

I’m not sure what’s going wrong here. I tried all the other solutions mentioned on other posts as well but non of them working.

Expected Behavior

The default route should land on the target page and would not produce any flickering or black glitch while moving in the app

Steps to Reproduce

Please follow the git https://github.com/ashishbairwa/router-bug-ionic for the walkthrough.

Alternatively:

  1. Create a new ionic react app with template as sidemenu.
  2. Add two pages in the app
  3. Add the routes for them and place a default route following this https://ionicframework.com/docs/react/navigation#fallback-route
  4. Implement buttons to move back and forth across page.
  5. Moving to any page right after entering an undefined route in the URL would lead to glitch

Code Reproduction URL

https://github.com/ashishbairwa/router-bug-ionic

Ionic Info

Ionic:

Ionic CLI : 6.18.1 (C:\Users\Ashish Bairwa\AppData\Roaming\npm\node_modules@ionic\cli)
Ionic Framework : @ionic/react 6.0.5

Capacitor:

Capacitor CLI : 3.3.3
@capacitor/android : 3.3.4
@capacitor/core : 3.3.3
@capacitor/ios : not installed

Utility:

cordova-res : not installed globally
native-run : 1.5.0

System:

NodeJS : v16.13.1 (C:\Program Files\nodejs\node.exe)
npm : 6.14.14
OS : Windows 10

Additional Information

Video proofs:
https://youtu.be/kuEK9mkZx84
https://youtu.be/wg8vt6HvBlY

Linked issue in forum: https://forum.ionicframework.com/t/flickering-black-glitch-while-redirecting-to-some-other-page/220096/8

@ionitron-bot ionitron-bot bot added the triage label Feb 28, 2022
@sean-perkins sean-perkins self-assigned this Feb 28, 2022
@sean-perkins
Copy link
Contributor

sean-perkins commented Feb 28, 2022

Hello @ashishbairwa thanks for moving this conversation into Github from our discord conversation.

To help narrow the reproduction information, can you confirm if this accurately describes the problem as you understand it (based on your reproduction app)?

  1. Start at /home.
  2. Click "Move to my name" button to navigate to /ashish.
  3. Click the "Move to" button to navigate between pages.
  4. See that the transitions are smooth between pages .
  5. In the browser address bar, enter an invalid URL, such as: /abc (press enter/navigate).
  6. You are navigated back to /home.
  7. Click "Move to" button to navigate.
  8. Continue to click "Move to" buttons.
  9. See that the transitions are flickering/animating incorrectly.

@ashishbairwa
Copy link
Author

Hello @ashishbairwa thanks for moving this conversation into Github from our discord conversation.

To help narrow the reproduction information, can you confirm if this accurately describes the problem as you understand it (based on your reproduction app)?

  1. Start at /home.
  2. Click "Move to my name" button to navigate to /ashish.
  3. Click the "Move to" button to navigate between pages.
  4. See that the transitions are smooth between pages .
  5. In the browser address bar, enter an invalid URL, such as: /abc (press enter/navigate).
  6. You are navigated back to /home.
  7. Click "Move to" button to navigate.
  8. Continue to click "Move to" buttons.
  9. See that the transitions are flickering/animating incorrectly.

Yes, idea is to use the fallback route once. Right after that animation seems to break.

@sean-perkins sean-perkins changed the title bug: flickering on moving to some page after implementing default route bug: React fallback route causes flicker transition when routing between pages Feb 28, 2022
@sean-perkins sean-perkins added package: react @ionic/react package type: bug a confirmed bug report labels Feb 28, 2022
@ionitron-bot ionitron-bot bot removed the triage label Feb 28, 2022
@sean-perkins
Copy link
Contributor

Awesome, thanks! I've updated the title and see the same behavior on my end. We will capture this as a bug and prioritize in an upcoming sprint.

@ashish-yourphysio
Copy link

Any progress on that?

@ashish-yourphysio
Copy link

I have cloned and updated all the dependencies to check if it's resolved but i can still see flickering without even doing any thing. @sean-perkins

@ashish-yourphysio
Copy link

It's been an year now. Do you guys have any update regarding this? @sean-perkins @liamdebeasi

@sean-perkins
Copy link
Contributor

@ashish-yourphysio this is still an open issue in our backlog. The team has worked on many issues in the past year. Issues are prioritized by a variety of metrics. For community issues we weigh them on potential impact and upvotes (interest).

The code is open source and freely available to provide assistance that can lead to this issue being resolved sooner. Additional debugging insight into the problematic code or a fix to the issue would be appreciated by both the team and the community.

I understand this issue may be extremely critical to your application, but we are small team that tries to solve the largest sum problems across Ionic Framework (web components, Angular, React and Vue), Ionic docs (documentation and live examples) and the Stencil Framework Wrappers for DX for frameworks consuming our web components.

We have improvements for routing in design, but it is unclear if they would have an immediate impact to this specific issue, without identifying the root cause to the transition flickering with the fallback route defined.

@nadavhalfon
Copy link

I can confirm that the problem still exists.
If the page starts and there is a redirect that occurs than the transitions are flickering, here is a stackblitz - you can see in App.tsx that there are comments, regarding the redirects.
Only "open" redirect causes flickering (btw only if you start the app from "/", if you refresh at "/customer/tabs/home" then everything works fine)
The commented Redirects together gets the same result but no flickering occurs, even if you start the page from "/".

https://stackblitz.com/edit/aexcxb?file=src%2FApp.tsx (to try the page refreshes you can open the demo in full page)
One last thing, the demo is not complicated so you'll see only drawback in performance but when there are more elements it's flickering in a bad way.

@jemantilla
Copy link

I can confirm this is still existing in Ionic 7. Any news?

@jemantilla
Copy link

jemantilla commented May 1, 2024

Okay i think i was able to fix it. Previously this is how we use router guards:

<IonRouterOutlet animated>          
           {COMMON_ROUTES.map((item) => (
            <AuthenticatedRoute
              key={item.path}
              path={item.path}
              component={item.component}
              exact
            />
          ))}
</IonRouterOutlet>

Simply put, we use custom component and either return the component or return a redirect depending on the authentication. Turns out flickering only happens on navigation if IonRoute is not a direct child of the IonRouterOutlet

so what i did instead is something like:

<IonRoute
          path={LOGIN}
          render={(props) => unauthenticatedRender(props, baseUser, SignIn)}
          exact={true}
        />

where unauthenticatedRender:

import isNull from "lodash/isNull";
import { Redirect } from "react-router-dom";
import { LazyExoticComponent, Suspense } from "react";

import { BaseUser } from "../../../Common/models/user";
import { COMPLETE_SIGN_UP, DASHBOARD } from "../../constants/routes";

export const unauthenticatedRender = (
  props: any,
  user: BaseUser | undefined | null,
  C: (() => JSX.Element) | LazyExoticComponent<() => JSX.Element>
) => {
  const path = props.location.pathname;
  if (user !== undefined && !isNull(user)) {
    if (!user.completedSignUp) {
      return <Redirect to={COMPLETE_SIGN_UP} />;
    }
    return <Redirect to={DASHBOARD} />;
  } else {
    return (
      <Suspense>
        <C {...props} />
      </Suspense>
    );
  }
};

This solved it for me! hope this can help

@nadavhalfon
Copy link

Okay i think i was able to fix it. Previously this is how we use router guards:


<IonRouterOutlet animated>          

           {COMMON_ROUTES.map((item) => (

            <AuthenticatedRoute

              key={item.path}

              path={item.path}

              component={item.component}

              exact

            />

          ))}

</IonRouterOutlet>

Simply put, we use custom component and either return the component or return a redirect depending on the authentication. Turns out flickering only happens on navigation if IonRoute is not a direct child of the IonRouterOutlet

so what i did instead is something like:


<IonRoute

          path={LOGIN}

          render={(props) => unauthenticatedRender(props, baseUser, SignIn)}

          exact={true}

        />

where unauthenticatedRender:


import isNull from "lodash/isNull";

import { Redirect } from "react-router-dom";

import { LazyExoticComponent, Suspense } from "react";



import { BaseUser } from "../../../Common/models/user";

import { COMPLETE_SIGN_UP, DASHBOARD } from "../../constants/routes";



export const unauthenticatedRender = (

  props: any,

  user: BaseUser | undefined | null,

  C: (() => JSX.Element) | LazyExoticComponent<() => JSX.Element>

) => {

  const path = props.location.pathname;

  if (user !== undefined && !isNull(user)) {

    if (!user.completedSignUp) {

      return <Redirect to={COMPLETE_SIGN_UP} />;

    }

    return <Redirect to={DASHBOARD} />;

  } else {

    return (

      <Suspense>

        <C {...props} />

      </Suspense>

    );

  }

};

This solved it for me! hope this can help

You are using "exact" which is not a fallback route and this is why you don't have the exact problem, the issue still persists:(

@zju1
Copy link

zju1 commented Oct 29, 2024

This is really serious bug. Any news? It's 2024 guys. It's been more than 2 years?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: react @ionic/react package type: bug a confirmed bug report
Projects
None yet
Development

No branches or pull requests

6 participants