在另一个组件道具更改上反应组件重新安装

时间:2019-03-25 12:40:59

标签: javascript reactjs redux

我有一个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)} />

2 个答案:

答案 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道具会计算差异并重新渲染差异

希望这会有所帮助! :)