【发布时间】:2017-11-21 14:22:35
【问题描述】:
我有以下场景:
1) 有一个父组件“ModuleListContainer”。
2) 一个模块(在模块列表中,也是一个子组件,但在此上下文中不感兴趣)在将鼠标悬停在列表中的模块项上时被选中。
3) 将鼠标悬停在模块上时,菜单应显示在模块的角落。
4) 选择模块时不应更新整个父组件,因为它可能是很长的模块列表,这就是为什么我在更新应该选择哪个模块时设置shouldComponentUpdate = false。
5) 菜单在父组件加载时加载,鼠标悬停在模块上时仅更新其位置。
这是父组件(简体)...
class ModuleListContainer extends Component {
constructor(props) {
super(props);
this.state = {
selectingModule: false,
currentlySelectedModule: nextProps.currentModule
}
}
shouldComponentUpdate(nextProps, nextState) {
if (nextState.selectingModule === true) {
this.setState({
selectingModule: false,
currentlySelectedModule: null
})
return false;
}
return true;
}
mouseEnterModule = (e, moduleItem) => {
const menu = document.getElementById('StickyMenu');
const menuPosition = calculateModuleMenuPosition(e.currentTarget);
if (moduleItem.ModuleId !== this.props.currentModuleId) {
this.props.actions.selectModule(moduleItem);
this.setState({
selectingModule: true
});
}
menu.style.top = menuPosition.topPos + 'px';
menu.style.left = menuPosition.leftPos + 'px';
}
render() {
return (
<div>
<section id="module-listing">
{/* ... list of mapped modules with mouseEnterModule event */}
</section>
<ModuleMenu {... this.props} currentlySelectedModule={this.state.currentlySelectedModule} />
</div>
);
}
}
这是菜单组件(简化版)...
class ModuleMenu extends Component {
constructor(props) {
super(props);
this.state = {
currentModule: this.props.currentlySelectedModule
};
}
clickMenuButton = () => {
console.log('CURRENT MODULE', this.state.currentModule);
}
render() {
return (
<div id="StickyMenu">
<button type="button" onClick={this.clickMenuButton}>
<span className="fa fa-pencil"></span>
</button>
</div>
);
}
}
当我在我的菜单组件中尝试从状态中console.log 当前模块时,我不断得到null。
我的问题是这是不是因为......
我已将 shouldComponentUpdate 设置为 false 并且菜单的状态未更新?
还是因为我没有重新渲染整个组件?
还是因为我把菜单和父组件一起加载了 并且在选择模块时不会重新渲染?
或者可能是上述几种情况的组合?
反应文档 (https://reactjs.org/docs/react-component.html) 说:
返回 false 不会阻止子组件重新渲染 当他们的状态发生变化时。
因此,我希望不是上述情况,因为我真的不想在选择模块时重新渲染整个组件。
【问题讨论】:
标签: javascript reactjs