我有React的性能问题,基本上我有两个紧凑的菜单,当页面滚动到距离顶部x距离时。我在滚动时看到Web应用程序的另一个组件正在做很少的动作,原因是它们正在重新渲染。
要知道当用户进行滚动时到顶部的距离我在componentDidMount()上有一个eventlistener,我认为这导致了问题,但我不确定,因为你知道反应稳定版本是相当新的我也是这项技术的新手:
以下是一些代码,正好是顶部栏,它是嵌套组件,当用户从顶部开出超过100px时触发紧凑菜单栏:
export default class AppTopBar extends Component {
constructor (props){
super(props);
this._bind("_handleOnScrollDocument");
this.state = {
StatusBar: false
}
}
componentDidMount() {
if (process.env.BROWSER) {
document.addEventListener("scroll", (e) => this._handleOnScrollDocument(e), true);
}
}
_handleOnScrollDocument(e) {
if (e.target.body.scrollTop > 100) {
this.setState({ StatusBar: true });
} else {
this.setState({ StatusBar: false });
}
}
render() {
return (
<div className="aui-core-apptopbar">
<StatusBar companies={this.props.companies} compactMenuItems={this.props.compactMenuItems} StatusBar={this.state.showCompactStatusBar}/>
<StatusBar companies={this.props.companies} userOptions={this.props.userOptions} compactMenuItems={this.props.compactMenuItems}/>
<MainNavBarView menuItems={this.props.menuItems}/>
</div>
);
}
}
我一直在研究和阅读有关组件生命周期和其他性能的信息:PURERENDERMIXIN
您是否了解更好的方法来获取轻量级Web应用程序并避免在滚动时重新呈现?
答案 0 :(得分:7)
假设您为班级创建了一个局部变量flag
。然后:
_handleOnScrollDocument(e) {
let newFlag = (e.target.body.scrollTop > 100);
if (flag !== newFlag) {
this.setState({showCompactStatusBar: newFlag});
flag = newFlag;
}
};
仅当您从一个方向或另一个方向传递scrollTop阈值(100)时,这将导致状态更改(和重新渲染)。否则我们根本不需要设置状态,从而避免调用render
。
答案 1 :(得分:2)
&#34;内置&#34;解决方案是使用shouldComponentUpdate
方法,它允许您比较当前return locals()
&amp; 传入 props
&amp;组件的state
组件props
然后如果您选择,请将state
方法短路:
render
答案 2 :(得分:0)
我的网页内有overflow: auto
CSS规则的组件上有滚动事件。我将滚动事件监听器附加到该组件,因为它被引导on this blog post。但是,将最后一个滚动位置设置为状态会严重破坏性能。
所以我在类构造函数中定义了最后一个位置并在那里更改了它,并避免了在每个滚动上重新渲染。
constructor(props){
super(props)
this.state = { scrollDirection: 'up' }
this.lastY = 0
}
如果方向改变,我只会改变状态。
handleListScroll(event){
const Y = event.currentTarget.scrollTop
const lastY = this.lastY
if (Y > lastY) {
scrollDirection = 'down'
if (this.state.scrollDirection === 'up') {
this.setState({
scrollDirection,
})
}
}
if (Y < lastY) {
scrollDirection = 'up'
if (this.state.scrollDirection === 'down') {
this.setState({
scrollDirection
})
}
}
this.lastY = Y
}