【问题标题】:Modal not showing up in react with react-bootstrap与 react-bootstrap 反应时未显示模态
【发布时间】:2020-05-31 06:37:48
【问题描述】:

我正在尝试创建一个模式,以便在单击 NavBar.Item Login/Register 时弹出登录/注册窗口。

我的模态定义如下:

import React from "react";
import '../assets/styles/GenericTheme.css'
import { Modal } from "react-bootstrap";

class LoginRegisterModal extends React.Component {  
    constructor(props, context) {
        super(props);
        this.state = {show: false};
    }

    open = () => {
        this.setState({show: true});
    }

    close = () => {
        this.setState({show: false});
    }

    render() {  
        return (         
     //   <Modal show={this.state.show} onHide={this.close} dialogClassName="popup-inner">
        <Modal show={this.state.show} fade={false} style={{width: "200px", display: "block"}}>
            <Modal.Body>test</Modal.Body>
        </Modal>
        );  
    }  
}  

export default LoginRegisterModal;

在 NavBar 中,我添加了对 Modal 的引用,如下所示:

import React, {}  from 'react';
import { Navbar, Nav, NavDropdown } from 'react-bootstrap';
import SearchForm from '../HeaderFooter/SearchForm';
import SiteLogo from '../../assets/images/village-logo.svg';
import '../../assets/styles/HeaderTheme.css'
import LoginRegisterModal from '../LoginRegisterModal';


class NavHeader extends React.Component {

    constructor(props, context) {
        super(props);
        this.state = {showLogin: false};
    }

    openLogin = () => {
        this.setState({showLogin: !this.state.showLogin});
    }

    render() {
        return (
            <div>
            <Navbar className="village-header" width="100" expand="lg">
                <Navbar.Brand href="/">
                    <img
                        src= { SiteLogo }
                        width="214"
                        height="28"
                        className="d-inline-block align-top"
                        alt="Village"
                    />
                </Navbar.Brand>
                <SearchForm />
                <Navbar.Toggle aria-controls="basic-navbar-nav" />
                <Navbar.Collapse id="basic-navbar-nav">
                    <Nav className="mr-auto village-header">
                    <Nav.Link href="/discover">Discover</Nav.Link>
                    <Nav.Link href="/create">Create</Nav.Link>
                    <Nav.Link href="/howitworks">How it Works</Nav.Link>
                    <Nav.Link ref="LoginRegisterModal" eventKey={1} href="#" onClick={this.openLogin}>Login/Register</Nav.Link>
                    <NavDropdown title="Profile" id="basic-nav-dropdown">
                        <NavDropdown.Item>Firstname LastName</NavDropdown.Item>
                        <NavDropdown.Divider />
                        <NavDropdown.Item href="/profile">Profile</NavDropdown.Item>
                        <NavDropdown.Item href="/messages">Messages</NavDropdown.Item>
                        <NavDropdown.Item href="/settings">Settings</NavDropdown.Item>
                        <NavDropdown.Item href="/logout">Logout</NavDropdown.Item>
                    </NavDropdown>
                    </Nav>
                </Navbar.Collapse>
            </Navbar>
            <LoginRegisterModal show={this.state.showLogin} />
            </div>
            );
        }
}

export default NavHeader;

当我点击登录/注册时:

&lt;Nav.Link ref="LoginRegisterModal" eventKey={1} href="#" onClick={this.openLogin}&gt;Login/Register&lt;/Nav.Link&gt;

什么都没有发生,没有弹出窗口或模式显示。我还在 NavBar 中添加了以下行

&lt;LoginRegisterModal show={this.state.showLogin} /&gt; 但没有任何变化。我还尝试添加 className 并将 z-layer 强制为 2,但效果不佳。

有什么想法吗? 问候

【问题讨论】:

    标签: css reactjs bootstrap-modal react-bootstrap


    【解决方案1】:

    您的模态组件不会“侦听”任何传递的道具,即从 NavHeader 传递的 show 道具。一个快速的脏方法是实现 componentDidUpdate 生命周期函数来检查 show 属性值的变化。还可以使用 show 属性值设置初始状态,以防挂载时显示为打开状态。

    class LoginRegisterModal extends React.Component {  
      constructor(props, context) {
        super(props);
        this.state = {
          show: props.show, // use the initial show value
        };
      }
    
      open = () => {
        this.setState({ show: true });
      }
    
      close = () => {
        this.setState({ show: false });
      }
    
      componentDidUpdate(prevProps) {
        const { show } = this.props;
        if (prevProps.show !== show) {
          if (show) {
            open(); // open if parent says to
          } else {
            close(); // close if parent says to
          }
        }
      }
    
      render() {  
        return (         
        //   <Modal
        //     show={this.state.show}
        //     onHide={this.close}
        //     dialogClassName="popup-inner"
        //   >
          <Modal
            show={this.state.show}
            fade={false}
            style={{width: "200px", display: "block"}}
          >
            <Modal.Body>test</Modal.Body>
          </Modal>
        );  
      }  
    }
    

    这允许父级切换模态框的显示状态,但如果模态框从内部关闭/解除怎么办。您可能需要某种方式向NavHeader 发出信号,表明模式已关闭,以便它可以“同步”其状态。 onHide 道具可以做到这一点,并且您已将其注释掉。我建议还向LoginRegisterModal API 公开onHide 属性。

    close = () => {
      this.setState({show: false});
      this.props.onHide();
    }
    

    父级这样使用

    <LoginRegisterModal
      show={this.state.showLogin}
      onHide={() => this.setState({ showLogin: false })}
    />
    

    但是,这会造成代码重复。让LoginRegisterModal 成为受控组件并简单地将showonHide 属性从NavHeader 传递给LoginRegisterModal 的内部Modal 组件可能是更好的设计。

    const LoginRegisterModal = props => (
      <Modal
        // pass props on through to Modal
        {...props}
        // set any props here that you don't want "overridable" by passed props
        fade={false}
        style={{ width: "200px", display: "block" }}
      >
        <Modal.Body>test</Modal.Body>
      </Modal>
    );
    

    【讨论】:

    • 非常感谢。你能给我一个受控组件的例子吗?我是新来的反应
    • @Seb 当然。我在答案的末尾添加了一个简单的示例。
    • 我的代码崩溃了,而且我看不到对 componentDidUpdate 的调用在哪里完成
    • 这是我得到的错误:'超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制了嵌套更新的数量以防止无限循环。'
    • @Seb 您能否更具体地了解崩溃的原因?什么组件在循环状态更新?
    猜你喜欢
    • 1970-01-01
    • 2015-10-31
    • 2021-08-04
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-03
    • 1970-01-01
    • 2018-06-30
    相关资源
    最近更新 更多