事务在React.Component上不起作用

时间:2020-06-12 09:27:51

标签: javascript css reactjs react-bootstrap

我按照一个示例来构建模式登录,并具有一个登录屏幕过渡的寄存器,但是我无法使该功能触发事务正常工作。

代码如下:

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

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

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

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

    componentDidMount(){
      this.signup.current.addEventListener('click', () => {
        this.container.current.classList.add('right-panel-active');
      });  

      this.signin.current.addEventListener('click', () => {
        this.container.current.classList.remove('right-panel-active');
      });  
    }

    componentDidUpdate(prevProps) {
        const { show } = this.props;
        if (prevProps.show !== show) {
          if (show) {
            this.open(); // open if parent says to
          } else {
            this.close(); // close if parent says to
          }
        }
    }

    requestSignIn = () => {
      this.close()
    }

    createAccount = () => {
      this.close()
    }

    requestForgotPassword = () => {

    }

    render() { 

      const styleModal = {
        marginTop: "15%",
        marginLeft: "30%",
        padding: 0,
        width:770,
        height:480,
        backgroundColor:"#ffffffff",
        borderRadius:21.5,
      } //style={styleModal}

      const styleHeaderWhite = {
        fontFamily: "Fredoka One",
        fontSize: "36px", 
        fontWeight: "normal",
        lineHeight: 1,
        color: "#ffffff"  
      }

      const styleHeaderBlack= {
        fontFamily: "Fredoka One",
        fontSize: "36px", 
        fontWeight: "normal",
        lineHeight: 1,
        color: "#333333"  
      }

      const styleTxtWhite = {
        fontFamily: "Source Sans Pro",
        fontSize: "14px", 
        fontWeight: "normal",
        lineHeight: 1,
        color: "#ffffff"  
      }

      const styleTxtBlack= {
        fontFamily: "Source Sans Pro",
        fontSize: "14px", 
        fontWeight: "normal",
        lineHeight: 1,
        color: "#616161"  
      }

      const whiteBtnStyle = {
        borderRadius: 21, 
        fontSize: "18px" ,
        fontWeight: "bold",
        textAlign: "center",
        color: "#ff7255",
        boxShadow: "0px 8px 18px 0 rgba(0,0,0,0.14)",
        paddingTop: "5px",
        paddingBottom: "7px",
        paddingLeft: "20px",
        paddingRight: "20px",
        backgroundColor: "#ffffff", 
        borderColor: "#ffffff",
        fontFamily: "Source Sans Pro",
    }

    const formStyle = {
      width: "280px",
      height: "40px",
      marginTop:"10px",
      borderRadius: 20,
      backgroundColor: "#f4f7f8",
      fontFamily: "Source Sans Pro",
      textAlign: "left",
    }

      const loginModal = <div class="containerLogin" ref={this.container}>
                          <div class="form-container sign-up-container">
                            <form action="#">
                              <h1 style={styleHeaderBlack}>Sign up.</h1>
                              <div class="social-container">
                              <a href="#" class="social"><i class="fab fa-google-plus-g"></i></a>
                              <a href="#" class="social"><i class="fab fa-google-plus-g"></i></a>
                              <a href="#" class="social"><i class="fab fa-linkedin-in"></i></a>
                              </div>
                              <span style={styleTxtBlack}>or use your email for registration</span>
                              <input style={formStyle} type="text" placeholder="Name" />
                              <input style={formStyle} type="email" placeholder="Email" />
                              <input style={formStyle} type="password" placeholder="Password" />
                              <button style={whiteBtnStyle} onClick={this.createAccount}>Sign Up</button>
                            </form>
                          </div>
                          <div class="form-container sign-in-container">
                          <form action="#">
                            <h1 style={styleHeaderBlack}>Sign in.</h1>
                            <div class="social-container">
                                <a href="#" class="social"><i class="fab fa-facebook-f"></i></a>
                                <a href="#" class="social"><i class="fab fa-google-plus-g"></i></a>
                                <a href="#" class="social"><i class="fab fa-linkedin-in"></i></a>
                            </div>
                            <span style={styleTxtBlack}>or use your account</span>
                            <input style={formStyle} type="email" placeholder="Email" />
                            <input style={formStyle} type="password" placeholder="Password" />
                            <a style={styleTxtBlack} href="#" onClick={this.requestForgotPassword} >Forgot your password?</a>
                            <button style={whiteBtnStyle} onClick={this.requestSignIn} >Sign In</button>
                          </form>
                          </div>
                          <div class="overlay-container">
                            <div class="overlay">
                              <div class="overlay-panel overlay-left">
                                  <h1 style={styleHeaderWhite}>Sign in.</h1>
                                  <p style={styleTxtWhite}>
                                    Nice to see you again.Login and continue the journey.
                                  </p>
                                  <button style={whiteBtnStyle} class="ghost" ref={this.signin}>Sign In</button>
                              </div>
                              <div class="overlay-panel overlay-right">
                                  <h1 style={styleHeaderWhite}>Hey, new friend!</h1>
                                  <p style={styleTxtWhite}>New to the Village? Sign up and start your journey</p>
                                  <button style={whiteBtnStyle} class="ghost" ref={this.signup}>Sign Up</button>
                              </div>
                            </div>
                          </div>
                        </div>;

      return (       
        <Modal className="modal" show={this.state.show}  size="lg" > 
            {loginModal}
        </Modal>
        );  
    }  
}  

export default LoginRegisterModal;


所以看来所有功能都可以在CSS上正常运行,但是我无法让这些功能正常工作

    componentDidMount(){
      this.signup.current.addEventListener('click', () => {
        this.container.current.classList.add('right-panel-active');
      });  

      this.signin.current.addEventListener('click', () => {
        this.container.current.classList.remove('right-panel-active');
      });  
    }

Css:

h1 {
    font-weight: bold;
    margin: 0;
}

p {
    font-size: 14px;
    font-weight: 100;
    line-height: 20px;
    letter-spacing: 0.5px;
    margin: 20px 0 30px;
}

span {
    font-size: 12px;
}

a {
    color: #333;
    font-size: 14px;
    text-decoration: none;
    margin: 15px 0;
}

button {
    border-radius: 200px;
    border: #ff7255;
    border-style: solid;
    border-width: 2px;
    border-bottom-left-radius: 20px;
    background-color: #ffffff;
    color: #ff7255;
    font-size: 20px;
    font-weight: bold;
    padding-top: 5px;
    padding-bottom: 7px;
    padding-left: 20px;
    padding-right: 20px;
    box-shadow: 0px 8px 18px 0 rgba(0,0,0,0.14);
    text-align: center;
}

button:active {
    transform: scale(0.95);
}

button:focus {
    outline: none;
}

button.ghost {
    background-color: #ffffff;
    border-color: #ffffff;
}

form {
    background-color: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    padding: 0 50px;
    height: 100%;
    text-align: center;
}

input {
    background-color: #eee;
    border: none;
    padding: 12px 15px;
    margin: 8px 0;
    width: 100%;
}

.social-container {
    margin: 20px 0;
}

.social-container a {
    border: 1px solid #dddddd;
    border-radius: 50%;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    margin: 0 5px;
    height: 40px;
    width: 40px;
}

.modalLogin {
    background-color: #ff4b2b;
    margin-top: "15%";
    margin-left: "30%";
    padding: 0;
    width:770px;
    height:480px;
    border-radius:21.5px;
}

.modal {
    display: none;
    position: fixed;
    z-index: 1;
    background-color: rgba(0, 0, 0, 0.25);
  }

.containerLogin {
    background-color: #ffffff;
    border-radius: 10px;
    box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.22);
    position: absolute;
    overflow: hidden;
    width: 768px;
    max-width: 100%;
    min-height: 480px;
}

.form-container {
    position: absolute;
    top: 0;
    height: 100%;
    transition: all 0.6s ease-in-out;
}

.sign-in-container {
    left: 0;
    width: 50%;
    z-index: 2;
}

.sign-up-container {
    left: 0;
    width: 50%;
    opacity: 0;
    z-index: 1;
}

.container.right-panel-active .sign-in-container {
    transform: translateX(100%);
}

.container.right-panel-active .sign-up-container {
    transform: translateX(100%);
    opacity: 1;
    z-index: 5;
    animation: show 0.6s;
}

@keyframes show {
    0%,
    49.99% {
        opacity: 0;
        z-index: 1;
    }

    50%,
    100% {
        opacity: 1;
        z-index: 5;
    }
}

.overlay-container {
    position: absolute;
    top: 0;
    left: 50%;
    width: 50%;
    height: 100%;
    overflow: hidden;
    transition: transform 0.6s ease-in-out;
    z-index: 100;
}

.container.right-panel-active .overlay-container {
    transform: translateX(-100%);
}

.overlay {
    background: #ff7255;
    background-size: cover;
    background-position: 0 0;
    color: #ffffff;
    position: relative;
    left: -100%;
    height: 100%;
    width: 200%;
    transform: translateX(0);
    transition: transform 0.6s ease-in-out;
}

.container.right-panel-active .overlay {
    transform: translateX(50%);
}

.overlay-panel {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    padding: 0 40px;
    text-align: center;
    top: 0;
    height: 100%;
    width: 50%;
    transform: translateX(0);
    transition: transform 0.6s ease-in-out;
}

.overlay-left {
    transform: translateX(-20%);
}

.container.right-panel-active .overlay-left {
    transform: translateX(0);
}

.overlay-right {
    right: 0;
    transform: translateX(0);
}

.container.right-panel-active .overlay-right {
    transform: translateX(20%);
}

我正在努力实现这一目标:https://www.youtube.com/watch?v=mUdo6w87rh4

单击时,我不断收到错误TypeError: Cannot read property 'addEventListener' of null

有什么主意吗? 谢谢

2 个答案:

答案 0 :(得分:0)

这意味着该行已损坏:this.signup.current.addEventListener

所以我认为解决方法是使componentDidMount成为箭头函数,以便this了解外部范围

尝试:componentDidMount = () => {

答案 1 :(得分:0)

首先,您使用的class错误。这是一个保留关键字,因此您必须在 React 中使用className

问题似乎是在安装组件后,按钮不在dom中,因此您无法添加事件监听器。一般来说,应避免将react和对addEventListener的标准调用混合使用,因为react具有一些非常特定的生命周期行为(正如您现在所体验到的)。你为什么不做这样的事情:

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

const loginModal = <div className={`containerLogin ${this.state.rightActive ? "right-panel-active" : ""}`}>

添加类的条件现在在组件中,并对新状态值rightActive状态的更改做出反应。同样不要忘记向按钮添加setState方法:

button style={whiteBtnStyle} class="ghost" onClick={() => this.setState({rightActive: true})}>Sign In</button>
button style={whiteBtnStyle} class="ghost" onClick={() => this.setState({rightActive: false})}>Sign Up</button>