【发布时间】:2016-12-03 05:39:45
【问题描述】:
我正在开发一个 react/redux 应用程序,并希望我的选项卡式组件将 redux 存储用于其活动选项卡状态。我试图以一种尽可能通用的方式来做到这一点,以便在我所有不同的选项卡组件之间共享功能;这导致了一个具有以下渲染方法的通用选项卡面板:
render () {
var activeTarget = this.props.panelState.tabPanes[this.props.tabPanelID] ? this.props.panelState.tabPanes[this.props.tabPanelID].activeTarget : this.props.defaultTarget;
var tabs = this.props.panelState.tabs;
var tabPanelID = this.props.tabPanelID;
// Add the tabPanelID and active properties to the tab pane children
const childrenWithProps = React.Children.map(this.props.children,
(child) => React.cloneElement(child, {
tabPanelID: tabPanelID,
active: activeTarget === child.props.id
})
);
// Render complete tab pane
return (
<div>
<ul className="nav nav-tabs">
{this.buildTabs()}
</ul>
<div className="tab-content">
{childrenWithProps}
</div>
</div>
);
}
但是,map 调用似乎会导致以下警告:
警告:setState(...):在现有状态转换期间无法更新(例如在
render或其他组件的构造函数中)。渲染方法应该是 props 和 state 的纯函数;构造函数副作用是一种反模式,但可以移动到 `componentWillMount
除非我弄错了,否则我实际上并没有改变这里的状态,所以我不确定为什么会收到这个警告。不过,我对反应比较陌生,所以很可能我遗漏了一些东西或误解了。
任何帮助将不胜感激。
编辑:对于那些想知道的人,这里是 buildTabs() 的内容:
buildTabs() {
var result = [];
var tabPanelID = this.props.tabPanelID;
// Create a tab for each tab in the props
for(var i = 0; i < this.props.tabs.length; i++) {
result.push
(
<Tab tabPanelID={this.props.tabPanelID} bare={this.props.tabs[i].bare} key={i} target={this.props.tabs[i].target}
active={this.props.panelState.tabPanes[tabPanelID] ?
(this.props.panelState.tabPanes[tabPanelID].activeTarget === this.props.tabs[i].target) :
this.props.tabs[i].target == this.props.defaultTarget}
additionalClasses={this.props.additionalTabClasses}>
{this.props.tabs[i].contents}
</Tab>
)
}
return result;
}
我之前只是没有包含它,因为我可以毫无问题地保留它,但删除对 Children.map 的调用会消除警告。
【问题讨论】:
-
您是否尝试在
buildTabs方法中调用 setState() ? -
是的,我正要说,
this.buildTabs()发生了什么? -
我现在已添加该代码供您查看。正如编辑中提到的,我之前没有包含它,因为它可以留在而不引起警告。
-
也许您的子组件中存在某些问题?