使用 React 和 React-bootstrap 应用程序进行不必要的模态渲染
Unnecessary modal renders with React and React-bootstrap app
我正在学习 React 并且正在开发一个简单的小应用程序。该应用程序包含一行,其中包含选项卡和下拉菜单。从该下拉菜单中,您可以为 adding/removing/editing 所述选项卡打开模式。
我注意到当应用程序启动时以及每次我单击任何选项卡时,所有模式都会调用它们的呈现方法,即使是当前选定的选项卡。我真的是 React 的新手,所以我很困惑这是否应该发生。不过,该应用程序似乎可以按预期运行。
下面是代码的超级简化版本,只有必要的部分:
app.js
class App extends React.Component {
// ...
// state is { modals: { addTab: false, editTab: false, removeTab: false } }
closeModal = (modalState) => {
const obj = this.state.modals;
obj[modalState] = false;
this.setState(obj);
}
render() {
<div className="App container-fluid">
// ...
<AddTabModal showModal={this.state.modals.addTab} closeModal={this.closeModal} ... />
// ...
</div>
}
}
AddTabModal.js
class AddTabModal extends React.Component {
// ...
render() {
// This gets triggered every time I click any tab or the dropdown menu.
// Even if the modal is not visible.
console.log('Render add tab modal');
return (
<Modal show={this.props.showModal} ... >
// ...
<Modal.Footer>
<Button onClick={() => { this.props.closeModal('addTab'); }}>Close</Button>
</Modal.Footer>
</Modal>
);
}
}
我还读到在 JSX 中使用箭头函数是一种糟糕的模式,但是如果我将按钮更改为:
<Button onClick={this.props.closeModal('addTab')}>Close</Button>
它应该仍然 运行 只有当我点击按钮时,对吧?但是应用程序从一开始就完全锁定,我收到 "Maximum update depth exceeded" 错误。我认为这与上述问题有关,因为我在应用程序中没有任何 componentWillUpdate/componentDidUpdate 方法。
您可以做几件事来优化:
- 确保传递到模式中的所有道具都是不可变的
- 将 close 函数提取到 class 方法中
- 使用
PureComponent
来防止渲染,除非道具发生变化
class AddTabModal extends PureComponent {
// ...
onCloseModal = () => {
this.props.closeModal('addTab');
}
render() {
// This gets triggered every time I click any tab or the dropdown menu.
// Even if the modal is not visible.
console.log('Render add tab modal');
return (
<Modal show={this.props.showModal} ... >
// ...
<Modal.Footer>
<Button onClick={this.onCloseModal}>Close</Button>
</Modal.Footer>
</Modal>
);
}
}
I also read that using arrow functions inside JSX is a bad pattern, but if I change the button to:
<Button onClick={this.props.closeModal('addTab')}>Close</Button>
这是因为 () => this.props.closeModal('addTab')
创建了一个新函数,调用时将关闭模态框。但是如果你只有 this.props.closeModal('addTab')
关闭模态函数会立即被调用。
避免额外匿名函数的方法是像上面的代码一样将其提取到 class 方法。
我正在学习 React 并且正在开发一个简单的小应用程序。该应用程序包含一行,其中包含选项卡和下拉菜单。从该下拉菜单中,您可以为 adding/removing/editing 所述选项卡打开模式。
我注意到当应用程序启动时以及每次我单击任何选项卡时,所有模式都会调用它们的呈现方法,即使是当前选定的选项卡。我真的是 React 的新手,所以我很困惑这是否应该发生。不过,该应用程序似乎可以按预期运行。
下面是代码的超级简化版本,只有必要的部分:
app.js
class App extends React.Component {
// ...
// state is { modals: { addTab: false, editTab: false, removeTab: false } }
closeModal = (modalState) => {
const obj = this.state.modals;
obj[modalState] = false;
this.setState(obj);
}
render() {
<div className="App container-fluid">
// ...
<AddTabModal showModal={this.state.modals.addTab} closeModal={this.closeModal} ... />
// ...
</div>
}
}
AddTabModal.js
class AddTabModal extends React.Component {
// ...
render() {
// This gets triggered every time I click any tab or the dropdown menu.
// Even if the modal is not visible.
console.log('Render add tab modal');
return (
<Modal show={this.props.showModal} ... >
// ...
<Modal.Footer>
<Button onClick={() => { this.props.closeModal('addTab'); }}>Close</Button>
</Modal.Footer>
</Modal>
);
}
}
我还读到在 JSX 中使用箭头函数是一种糟糕的模式,但是如果我将按钮更改为:
<Button onClick={this.props.closeModal('addTab')}>Close</Button>
它应该仍然 运行 只有当我点击按钮时,对吧?但是应用程序从一开始就完全锁定,我收到 "Maximum update depth exceeded" 错误。我认为这与上述问题有关,因为我在应用程序中没有任何 componentWillUpdate/componentDidUpdate 方法。
您可以做几件事来优化:
- 确保传递到模式中的所有道具都是不可变的
- 将 close 函数提取到 class 方法中
- 使用
PureComponent
来防止渲染,除非道具发生变化
class AddTabModal extends PureComponent {
// ...
onCloseModal = () => {
this.props.closeModal('addTab');
}
render() {
// This gets triggered every time I click any tab or the dropdown menu.
// Even if the modal is not visible.
console.log('Render add tab modal');
return (
<Modal show={this.props.showModal} ... >
// ...
<Modal.Footer>
<Button onClick={this.onCloseModal}>Close</Button>
</Modal.Footer>
</Modal>
);
}
}
I also read that using arrow functions inside JSX is a bad pattern, but if I change the button to:
<Button onClick={this.props.closeModal('addTab')}>Close</Button>
这是因为 () => this.props.closeModal('addTab')
创建了一个新函数,调用时将关闭模态框。但是如果你只有 this.props.closeModal('addTab')
关闭模态函数会立即被调用。
避免额外匿名函数的方法是像上面的代码一样将其提取到 class 方法。