Javascript setState(…):无法在现有状态转换期间更新(例如在“render”或其他组件的构造函数中)

Javascript setState(…):无法在现有状态转换期间更新(例如在“render”或其他组件的构造函数中),javascript,reactjs,Javascript,Reactjs,我有以下几个部分: const VIEW_PROFILE = 'profile' const VIEW_SAA = 'saa' const VIEW_DOCUMENTS = 'documents' const VIEW_FINANCIERS = 'viewFinancierInfo' class ViewFinancier extends Component { constructor(props) { super(props) this.state = { s

我有以下几个部分:

const VIEW_PROFILE = 'profile'
const VIEW_SAA = 'saa'
const VIEW_DOCUMENTS = 'documents'
const VIEW_FINANCIERS = 'viewFinancierInfo'

class ViewFinancier extends Component {
  constructor(props) {
    super(props)
    this.state = {
      selectedNavigation: VIEW_PROFILE,
      financierId: this.props.location.state.financierDetails.financierId,
      defaultLoading: false
    }

    this.handleChangeNav = this.handleChangeNav.bind(this)
    this.handleCancelButton = this.handleCancelButton.bind(this)
  }

  componentWillMount(props) {
    this.props.loadFinancierProfile(this.props.location.state.financierDetails.financierId)
  }

  componentWillReceiveProps(newProps) {
    this.setState({
      defaultLoading: true,
      viewfinancierprofiledata: newProps.viewfinancierprofiledata
    })
  }

  handleChangeNav(e) {
    var selectedNavigation = e.target.attributes.getNamedItem('value').value
    this.setState({
      selectedNavigation: selectedNavigation
    })
  }

  handleCancelButton(changingState) {
    this.setState({
      selectedNavigation: changingState
    })
  }

  render() {
    if (this.state.defaultLoading === false) {
      return (
        <div className="tabledataloading tabletext">
          Please wait while the data is loading <img alt="Loading..." src={loadingimg} />
        </div>
      )
    } else if (this.state.selectedNavigation === VIEW_FINANCIERS) {
      this.props.history.push('/financier/')
      return null
    } else {
      return (
        <div id="lesse-info-component-wrapper" className="melody-common-container">
          <div id="header-wrapper">
            <h1 className="melody-common-module-title">VIEW FINANCIER INFO</h1>
          </div>
          <div id="navigation-wrapper">
            <ul id="add-financier-info-nav" className="topnavpad">
              <li
                value={VIEW_PROFILE}
                onClick={this.handleChangeNav}
                className={'add-financier-info-nav-item ' + (this.state.selectedNavigation === VIEW_PROFILE ? 'active' : '')}>
                PROFILE
              </li>
              <li
                value={VIEW_SAA}
                onClick={this.handleChangeNav}
                className={'add-financier-info-nav-item ' + (this.state.selectedNavigation === VIEW_SAA ? 'active' : '')}>
                SAA
              </li>
              <li
                value={VIEW_DOCUMENTS}
                onClick={this.handleChangeNav}
                className={'add-financier-info-nav-item ' + (this.state.selectedNavigation === VIEW_DOCUMENTS ? 'active' : '')}>
                DOCUMENTS
              </li>
            </ul>
          </div>
          {this.state.selectedNavigation === VIEW_PROFILE
            ? <ViewFinancierProfile financierId={this.props.financierId} onCancelHandler={this.handleCancelButton} />
            : null}
          {this.state.selectedNavigation === VIEW_SAA
            ? <ViewFinancierSAA financierId={this.props.financierId} onCancelHandler={this.handleCancelButton} />
            : null}
          {this.state.selectedNavigation === VIEW_DOCUMENTS
            ? <ViewFinancierDocument financierId={this.props.financierId} onCancelHandler={this.handleCancelButton} />
            : null}
        </div>
      )
    }
  }
}

const mapStateToProps = state => {
  return {
    viewfinancierprofiledata: state.viewfinancierprofiledata
  }
}

const mapDispatchToProps = dispatch => {
  return {
    loadFinancierProfile: financierId => dispatch(viewFinancierProfileAction.loadFinancierProfile(financierId))
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(ViewFinancier)
const VIEW\u PROFILE='PROFILE'
const VIEW_SAA='SAA'
const VIEW_DOCUMENTS='DOCUMENTS'
const VIEW_financiars='viewfinanciarinfo'
类ViewFinanciar扩展组件{
建造师(道具){
超级(道具)
此.state={
选择导航:查看配置文件,
FinancialId:this.props.location.state.financialDetails.FinancialId,
默认加载:false
}
this.handleChangeNav=this.handleChangeNav.bind(this)
this.handleCancelButton=this.handleCancelButton.bind(this)
}
组件安装(道具){
this.props.LoadFinanciarProfile(this.props.location.state.FinanciarDetails.FinanciarID)
}
组件将接收道具(新道具){
这是我的国家({
默认加载:true,
ViewFinanciarProfileData:newProps.ViewFinanciarProfileData
})
}
handleChangeNav(东){
var selectedNavigation=e.target.attributes.getNamedItem('value').value
这是我的国家({
selectedNavigation:selectedNavigation
})
}
手柄取消按钮(更改状态){
这是我的国家({
所选导航:changingState
})
}
render(){
if(this.state.defaultLoading===false){
返回(
正在加载数据,请稍候
)
}else if(this.state.selectedNavigation==查看\u金融家){
this.props.history.push(“/financiar/”)
返回空
}否则{
返回(
查看金融家信息
  • 轮廓
  • 萨阿
  • 文件
{this.state.selectedNavigation==查看\u配置文件 ? :null} {this.state.selectedNavigation==查看\u SAA ? :null} {this.state.selectedNavigation==查看\u文档 ? :null} ) } } } 常量mapStateToProps=状态=>{ 返回{ ViewFinanciarProfileData:state.ViewFinanciarProfileData } } const mapDispatchToProps=调度=>{ 返回{ LoadFinanciarProfile:FinanciarID=>dispatch(查看FinanciarProfileAction.LoadFinanciarProfile(FinanciarID)) } } 导出默认连接(mapStateToProps、mapDispatchToProps)(ViewFinanciar)
在执行时,我得到警告:
警告:setState(…):无法在现有状态转换期间更新(例如在
render
或其他组件的构造函数中)。渲染方法应该是道具和状态的纯函数;构造函数的副作用是一种反模式,但可以移动到
componentWillMount`

查看控制台时,我发现代码片段
this.props.history.push('/financiar/')
抛出了错误

在进一步研究堆栈溢出中的其他类似问题时,我还发现这实际上是在render方法下设置父状态,这是不允许的


但是现在我不知道如何才能达到我想要的条件。

组件
道具
不应该自行变异。我认为在这种情况下有两种解决方案

  • 此.props.history
    复制到
    状态
    ,并通过调用
    设置状态
    历史进行变异。将
    selectedNavigation
    的检查置于
    render
    之外。例如(只是我的想法,请根据您的应用程序逻辑进行修改):
  • class ViewFinanciar扩展组件{
    建造师(道具){
    超级(道具)
    此.state={
    ...
    历史=道具。历史,
    ...
    }
    ...
    }
    组件将接收道具(新道具){
    这是我的国家({
    历史:新道具,历史,
    ...
    })
    }
    handleChangeNav(东){
    var selectedNavigation=e.target.attributes.getNamedItem('value').value;
    这是我的国家({
    selectedNavigation:selectedNavigation
    })
    此.history检查(selectedNavigation);
    }
    手柄取消按钮(更改状态){
    这是我的国家({
    所选导航:changingState
    });
    这是历史检查(昌宁州);
    }
    历史检查(导航){
    如果(资产净值===查看融资人){
    历史推送(“/金融家/”);
    };
    this.setState(历史:历史);
    }
    render(){
    ...
    }else if(this.state.selectedNavigation==查看\u金融家){
    返回空
    }
    ...
    }
    
    }
    对于第#1点,我如何在渲染方法中使用setState来改变历史,情况也是一样,对吗?我根据我的代码流使用了第1种方法。。。我对这个很在行。谢谢你的帮助