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