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种方法。。。我对这个很在行。谢谢你的帮助