我有一个react-router-redux应用程序,该应用程序在所有页面的顶部都有一个VoIP呼叫处理栏。voip 栏有一个计时器,用于计算呼叫的时间,其间隔每秒递增一次。
出于某种原因,每次 voip 栏重新渲染道具更改的原因时,显示的页面(使用 react 路由器)都会重新挂载。我不知道为什么,因为 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)} />
您可以尝试使用shouldComponentUpdate()
方法:
https://reactjs.org/docs/react-component.html#shouldcomponentupdate
React 的文档说:
shouldComponentUpdate(nextProps, nextState)
使用shouldComponentUpdate()
让 React 知道组件的输出是否不受当前状态或 props 变化的影响。默认行为是在每次状态更改时重新呈现,在绝大多数情况下,应依赖默认行为。
shouldComponentUpdate()
在接收新道具或状态时在渲染之前调用。默认值为 true。初始渲染或使用 forceUpdate() 时不调用此方法。
我最近在 react-router 上遇到了同样的问题。 我犯的错误是在使用 react-router 的Route
时使用component
道具而不是render
道具。
根据他们的文档,当路由器中的任何内容发生变化时,component
prop 会重新挂载整个路由。但是,render
道具会计算差异并重新呈现差异
希望这有帮助! :)