简体   繁体   中英

React Component is rendered 5 times, Ionic 4

I am developing an app with a dashboard to show some data. I can see on chrome's console the render method is called 5 times, and the app page displays a very annoying effect of being re-rendered. How can I avoid the render method to be called that many times, and the annoying re-rendering/bouncing effect? I am loading the Dashboard page.

Chrome Console:

在此处输入图像描述

App.tsx:

<IonApp>
    <IonReactRouter>
      <SideMenu></SideMenu>
      <IonPage id="main">
        <IonTabs>
          <IonRouterOutlet id="main">
            <Switch>
              <Route exact path="/login" render={(props) => <Login {...props} />} />
              <PrivateRoute path="/dashboard" component={Dashboard} />
              <PrivateRoute path="/list/:status" component={List} />
              <PrivateRoute path="/detail/:id" component={Detail} />
              <Redirect from="/" to="/dashboard"></Redirect>
              <Route component={NotFound} />
            </Switch>
          </IonRouterOutlet>
          <IonTabBar slot="bottom">
            <IonTabButton tab="tabnew" href="/addnew">
              <IonIcon icon={add} />
              <IonLabel>Add an Item</IonLabel>
            </IonTabButton>
          </IonTabBar>
        </IonTabs>
      </IonPage>
    </IonReactRouter>
  </IonApp>

PrivateRoute:

interface PrivateRouteProps extends RouteProps {
    component: any
}

const PrivateRoute: FunctionComponent<PrivateRouteProps> = ({ component: Component, ...rest }) => (

    <Route {...rest} render={(props) => {
        const currentUser: string | null  =  localStorage.getItem("jwt");

        if (!currentUser) {
            return <Redirect to={{ pathname: '/login' }} />
        }

        console.log('PrivateRoute returns Component');
        return <Component {...props} />
    }} />
);

export default PrivateRoute;

Dashboard:

type Props = {};
type PropsType = RouteComponentProps<Props>

type State = {
  dashboard: {
    borrowed: string,
    stored: string,
    available: string,
    lost: string,
    busted: string,
  },
  error: string
};
class Dashboard extends PureComponent <PropsType, State> {  

  constructor (props: PropsType) {
    super(props)
    this.state = {
      dashboard: {
        borrowed: "4",
        stored: "6",
        available: "2",
        lost: "3",
        busted: "1",
      },
      error: ''
    }
  }

  componentDidMount() {
    console.log("Dashboard ComponentDidMount")
  }

  render() {
    console.log("Render");
    var availableClass= "dashboard-elem dashboard-number " + (this.state.dashboard.available === "0" ?  "text-success" : "text-warning");
    var lostClass  = "dashboard-elem dashboard-number " + (this.state.dashboard.lost=== "0" ?  "text-success" : "text-danger" );
    var bustedClass = "dashboard-elem dashboard-number " + (this.state.dashboard.busted  === "0" ?  "text-success" : "text-danger" );

    return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonButtons slot="start">
            <IonMenuButton autoHide={false}></IonMenuButton>
          </IonButtons>
          <IonTitle>
            <div className="header-logo">
              <img src="/assets/img/logo.png" alt="logo"></img>
            </div>
          </IonTitle>
        </IonToolbar>
      </IonHeader>
      <IonContent>
        <IonCard>
          <IonCardContent>
            <IonSearchbar searchIcon="search" showCancelButton="always" value="Search your container"></IonSearchbar>
          </IonCardContent>
          <IonCardContent className="font-weight-bold">
            <IonCard className="card-body" href="/list/borrowed">
              <div className="dashboard-elem">Borrowed:</div>
              <div className="dashboard-elem text-success dashboard-number">{this.state.dashboard.borrowed}</div>
            </IonCard>
            <IonCard className="card-body">
              <div className="dashboard-elem">Stored:</div>
              <div className="dashboard-elem text-success dashboard-number">{this.state.dashboard.stored}</div>
            </IonCard>
            <IonCard className="card-body">
              <div className="dashboard-elem">Available:</div>
              <div className={availableClass}>{this.state.dashboard.available}</div>
            </IonCard>
            <IonCard className="card-body">
              <div className="dashboard-elem">Lost:</div>
              <div className={lostClass}>{this.state.dashboard.lost}</div>
            </IonCard>
            <IonCard className="card-body">
              <div className="dashboard-elem">Busted:</div>
              <div className={bustedClass}>{this.state.dashboard.busted}</div>
            </IonCard>
          </IonCardContent>
        </IonCard>
      </IonContent>
    </IonPage>
  )};
};

export default withRouter(Dashboard);

Issue solved by removing the <IonRouterOutlet> and using just the React's <Switch> . According to Ionic's documentation IonRouterOutlet should only be used in Angular Apps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM