Javascript 反应组分渲染5次,离子4次

Javascript 反应组分渲染5次,离子4次,javascript,reactjs,react-router,react-hooks,ionic4,Javascript,Reactjs,React Router,React Hooks,Ionic4,我正在开发一个带有仪表板的应用程序来显示一些数据。我可以在chrome的控制台上看到render方法被调用了5次,应用程序页面显示了一种非常恼人的重新渲染效果。如何避免多次调用渲染方法,以及令人讨厌的重新渲染/反弹效果?我正在加载仪表板页面 Chrome控制台: <IonApp> <IonReactRouter> <SideMenu></SideMenu> <IonPage id="main">

我正在开发一个带有仪表板的应用程序来显示一些数据。我可以在chrome的控制台上看到render方法被调用了5次,应用程序页面显示了一种非常恼人的重新渲染效果。如何避免多次调用渲染方法,以及令人讨厌的重新渲染/反弹效果?我正在加载仪表板页面

Chrome控制台:

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

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

} />
添加项目
私人路线:

<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>
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;
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);
接口PrivateRouteProps扩展了RouteProps{
组成部分:任何
}
常量PrivateRoute:FunctionComponent=({component:component,…rest})=>(
{
const currentUser:string | null=localStorage.getItem(“jwt”);
如果(!currentUser){
返回
}
log('privatroute返回组件');
返回
}} />
);
导出默认私有路由;
仪表板:

<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>
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;
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);
type Props={};
类型PropsType=路由组件PROPS
类型状态={
仪表板:{
借用:字符串,
存储:字符串,
可用:字符串,
丢失:字符串,
破裂:弦,
},
错误:字符串
};
类仪表板扩展了PureComponent{
构造器(道具:PropsType){
超级(道具)
此.state={
仪表板:{
借用:“4”,
存储:“6”,
可供选择:“2”,
迷失:“3”,
破译:“1”,
},
错误:“”
}
}
componentDidMount(){
log(“仪表板组件安装”)
}
render(){
控制台日志(“呈现”);
var availableClass=“dashboard elem dashboard number”+(this.state.dashboard.available==“0”?“文本成功”:“文本警告”);
var lostClass=“dashboard elem dashboard number”+(this.state.dashboard.lost==“0”?“文本成功”:“文本危险”);
var bustedClass=“dashboard elem dashboard number”+(this.state.dashboard.busted==“0”?“文本成功”:“文本危险”);
返回(
借来:
{this.state.dashboard.followed}
存储:
{this.state.dashboard.stored}
提供:
{this.state.dashboard.available}
迷路的:
{this.state.dashboard.lost}
破产:
{this.state.dashboard.busted}
)};
};
使用路由器导出默认值(仪表板);

通过移除
并仅使用React的
解决问题。根据爱奥尼亚的文档,它只能在角度应用程序中使用。

如果道具发生变化,它将重新渲染-当您将所有道具传递给它时,如果有任何变化,它将重新渲染。-您可以控制这是shouldComponentUpdate()re: