我有一个react-router-redux应用程序,该应用程序在所有页面的顶部都有一个voip呼叫处理栏。语音提示栏上有一个计时器,用于计算通话时间,间隔时间每秒钟增加一次。
由于某种原因,每次语音条重新出现引起道具改变时,显示的页面(使用React Router)都会重新安装。我不知道为什么,因为voip栏甚至不是页面的孩子/父母。
我真的不知道为什么会这样。我以为路线可能会在每次道具更改时发生变化,从而导致重新安装,但这不是问题。
布局:
<div className={classes.layout} id='layout'>
<Header isAuthenticated={this.props.isAuthenticated} username={this.props.username} />
<VoipBar />
<main className={classes.content} id='page-wrap'>
{this.props.children}
</main>
{/* <Footer /> */}
</div>
如您所见,VoipBar不是页面的父级(页面是主标记中的子级)。
被调用的间隔是每秒分派一个动作的间隔。动作的减速器是这样的:
case actionTypes.UPDATE_PHONE_TIMER:
return {
...state,
seconds: state.seconds + 1,
time: formatTime(state.seconds + 1)
}
我正在VoipBar组件中以这种方式使用“时间”:
<div className={classes.twilioLog} style={{color: this.props.logColor}}>{`${this.props.twilioLog}${this.props.time ? `: ${this.props.time}` : '' }`}</div>
总结,voipbar上的计时器应根据通话时间每秒更新一次,并且完全不会影响页面。现在,每次voipbar更新时,整个页面都会重新安装。
编辑:我发现,如果删除包装页面的HOC,该页面将不再重新渲染。由于某种原因,HOC现在会在每次voipbar道具更改时重新呈现。 HOC用于身份验证(纯前端)。我仍然不明白那里发生了什么。这是我的HOC:
import React from 'react';
import { connect } from 'react-redux';
import * as actions from '../../store/actions';
export default function (ComposedComponent) {
class Authenticate extends React.Component {
componentDidMount() {
if (!this.props.username || !this.props.role || !this.props.siteAccess) this.props.logout();
}
render() {
return <ComposedComponent {...this.props} />
}
}
const mapStateToProps = (state) => {
return {
username: state.auth.username,
role: state.auth.role,
siteAccess: state.auth.siteAccess
};
};
const mapDispatchToProps = dispatch => {
return {
logout: () => dispatch(actions.logout())
};
};
return connect(mapStateToProps, mapDispatchToProps)(Authenticate);
};
相关路线:
<Route path='/profile/person/:personId' component={withAuth(PersonProfile)} />
答案 0 :(得分:1)
您可以尝试使用shouldComponentUpdate()
方法:
https://reactjs.org/docs/react-component.html#shouldcomponentupdate
React的文档说:
shouldComponentUpdate(nextProps, nextState)
使用shouldComponentUpdate()
让React知道组件的输出是否不受当前状态或道具更改的影响。默认行为是在每次状态更改时重新呈现,并且在大多数情况下,您应该依赖默认行为。
shouldComponentUpdate()
。默认为true。初始渲染或使用forceUpdate()时不会调用此方法。
答案 1 :(得分:0)
我最近在react-router上遇到了同样的问题。
我犯的错误是在使用react-router的component
时使用render
道具而不是Route
道具。
根据他们的文档,component
属性会在路由器中的任何内容发生更改时重新安装整个路由。但是,render
道具会计算差异并重新渲染差异
希望这会有所帮助! :)