说我有一个模板模态反应组件,如下所示(简化了我的问题,使其变得更加清晰):
function Modal(props) {
const hide=()=>{
document.querySelector('#modal').style.display='none';
};
return (
<div id = 'modal' className='modal'>
{props.children}
//close button and so on...
</div>
);
}
export default Modal;
现在,我将为特定目的制作模态的更特定版本。因此,我传递了
Modal
功能组件children
,它们将是AreYouSureModal
的孙代:function AreYouSureModal(props) {
yesAction = ()=>{props.yesAction}
noAction = ()=>{props.noAction}
const children = <fragment>
Are you sure?
<button onclick = {this.yesAction /*and call .hide() in Modal*/}>Yes</button>
<button onclick = {this.noAction /*and call .hide() in Modal*/}>No</button>
</fragment>;
return <Modal children = {children} />
}
export default AreYouSureModal;
现在
yesAction
和noAction
将会是我从AreYouSureModal
父级那里获得的东西,所以我要传递这些函数。但是这些按钮还需要调用模板hide()
功能组件中的Modal
函数。做这个的最好方式是什么?我是否可以在
yesAction
的AreYouSureModal
函数中调用Modal
子级的方法?还是在Modal
函数中使AreYouSureModal
成为常量并将这些方法绑定到该常量之前,将其传递给我?换句话说,我该如何创建在子代中调用函数的孙子代?还是我完全以完全错误的方式尝试执行此操作?
最佳答案
我建议不要使用样式来隐藏模态,而建议使用React Portals。免责声明:我还没有使用钩子,所以我将使用类组件来编写它。
无论如何,您的Modal
-组件将如下所示:
class Modal extends React.Component {
render() {
if (!this.props.isOpen) return null
return (
ReactDOM.createPortal(
<div className="modal">
{this.props.children}
</div>
)
)
}
}
然后,您的
AreYouSureModal
-组件将如下所示:class AreYouSureModal extends React.Component {
handleYesAction = () => {
/* Do something */
this.props.onClose()
}
handleNoAction = () => {
/* Do something */
this.props.onClose()
}
render() {
return (
<Modal isOpen={this.props.isOpen}>
<React.Fragment>
<h2>Are you sure?</h2>
<button onClick={this.handleYesAction}>Yes</button>
<button onClick={this.handleNoAction}>No</button>
</React.Fragment>
</Modal>
)
}
}
最后,从中呈现
AreYouSureModal
的组件将保留模态的状态:class App extends React.Component {
state = { isAreYouSureModalOpen: false }
openAreYouSureModal = () => this.setState({ isAreYouSureModalOpen: true })
closeAreYouSureModal = () => this.setState({ isAreYouSureModalOpen: false })
render() {
return (
<React.Fragment>
<button onClick={this.openAreYouSureModal}>Open modal</button>
<AreYouSureModal
onClose={this.closeAreYouSureModal}
isOpen={this.state.isAreYouSureModalOpen}
/>
</React.Fragment>
)
}
}