首页 > 解决方案 > 回调控制模态显示

问题描述

我已经建立了一个模式来显示登录/注册模式。默认情况下,模态框由另一个组件使用 props 打开show。当此组件调用模态框时,此功能有效。

模态Form也是从我的 Header.js 调用的,如下所示:

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

在这种情况下,showLogin单击 时状态设置为 true Login/Register<LoginRegisterform现在显示模式,因为displayPopupprops 设置为true

代码如下:

表单.js

const Form = ({ initialState = STATE_SIGN_UP, displayPopUp}) => {
  const [mode, toggleMode] = useToggle(initialState);
  const [display, toggleDisplay] = useToggleDisplay(displayPopUp);

  console.log('----------------------------------------------------------')
  console.log('displayPopUp: ' + displayPopUp)
  console.log('display: ' + display)
  console.log('toggleDisplay: ' + toggleDisplay)
  console.log('----------------------------------------------------------')

 
  return (
    <Modal className="modal" show={displayPopUp}  size="lg">
        <Container pose={mode === STATE_LOG_IN ? "signup" : "login"}>
        <div className="container__form container__form--one">
            <FormLogin mode={mode} toggleDisplay={toggleDisplay} />
        </div>
        <div className="container__form container__form--two">
            <FormSignup mode={mode} toggleDisplay={toggleDisplay}/>
        </div>
        <Overlay toggleMode={toggleMode} mode={mode} />
        </Container>
    </Modal>
  );
};

在 中FormLogin,我确实有一个Cancel按钮,可让我在需要时关闭位于 modal 中的模式Form.js。但是,我不知道如何通过更改关闭控件在类show中时的参数来关闭模式Form.jsFormLogin

FormLogin.js

import React from 'react'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'

import SocialButton from './styled/SocialButton'
import SlidingForm from './styled/SlidingForm'

import WhiteButton from '../../materialdesign/WhiteButton'

import { faFacebook, faGoogle, faLinkedinIn } from '@fortawesome/free-brands-svg-icons'

import Auth from '../../../data/network/Auth';
import Constant from '../../../config/Constant';

import CancelIcon from '@material-ui/icons/Cancel';


class FormLogin extends React.Component {

    constructor(props, context) {
        super(props);
        this.state = {
          email: '',
          password: '',
          loading: false,
          error: '',
          toggleDisplay: this.props.toggleDisplay
        };
    }

    requestSignIn = async (event) => {
        event.preventDefault();
  
        this.setState({loading: true})
  
        try {
          const authData = await Auth.getToken(`${this.state.email}`, `${this.state.password}`);
          sessionStorage.setItem(Constant.ALL, authData)
          sessionStorage.setItem(Constant.AUTH_TOKEN, authData.token)
          sessionStorage.setItem(Constant.DISPLAY_NAME, authData.user_display_name)
          sessionStorage.setItem(Constant.EMAIL, authData.user_email)
          sessionStorage.setItem(Constant.NICENAME, authData.user_nicename)
  
          window.open("/", "_self") //to open new page
          this.setState({loading: false })
          this.close()
        } catch (error) {
          console.warn("Connection to WP - Auth Token failed ")
          console.error(error);
        } 
      }

    requestForgotPassword = () => {
    }

    handleOnChange = (event) => {
        this.setState({[event.target.name]: event.target.value})
    }

    render(){

        const { email, password } = this.state;
        
        return(
            <SlidingForm>  
                 <div style={{textAlign:"left"}}>
                    <CancelIcon style={{ color: "#ff7255" }} onClick={() => this.state.toggleDisplay(false) }/>
                </div>         
                <h1 style={titleStyle}>Sign in</h1>
                <div style={{textAlign: "center"}}>
                <SocialButton>
                    <FontAwesomeIcon icon={faFacebook} />
                </SocialButton>
                <SocialButton>
                    <FontAwesomeIcon icon={faGoogle} />
                </SocialButton>
                <SocialButton>
                    <FontAwesomeIcon icon={faLinkedinIn} />
                </SocialButton>
                </div>
                <p style={txtStyle}>or use your account</p>
                <form style={{textAlign: "center"}}>
                <input style={formStyle} placeholder="Email" type="text" name="email" value={ email } onChange={ this.handleOnChange }/>
                <input style={formStyle} placeholder="Password" type="password" name="password" value={ password } onChange={ this.handleOnChange } />
                </form>
                <p style={txtSpan}>
                <a href="#" onClick={this.requestForgotPassword}>Forgot your password?</a>
                </p>
                <div style={{textAlign: "center", marginTop: "15px"}}>
                    <WhiteButton text="Sign in" onClick={this.requestSignIn}></WhiteButton>
                </div>
            </SlidingForm>
        );
    }
}

export default FormLogin

现在我正在这样做:

<CancelIcon style={{ color: "#ff7255" }} onClick={() => this.state.toggleDisplay(false)

但它不起作用,似乎无法控制Form.js.

切换显示代码如下:

import { useState } from 'react'

export const STATE_SHOW = true
export const STATE_HIDE = false

const useToggleDisplay = initialDisplayState => {
  const [display, setDisplay] = useState(initialDisplayState)
  const toggleDisplay = () =>
    setDisplay(display === false ? true : false)
    console.log('-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%')
    console.log('display: ' + display)
    console.log('toggleDisplay: ' + toggleDisplay)
    console.log('-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%')
  return [display, toggleDisplay]
}

export default useToggleDisplay

整体逻辑:

在触发关闭时能够设置的最佳选项是show什么?falseForm.jsFormLogin.js

谢谢

标签: javascriptreactjs

解决方案


无需将toggleDisplayprop 分配给 local state,只需直接调用prop。这应该适用于将<Form />display状态更新为false

另外,您打算<CancelIcon />切换modal打开/关闭状态,还是只是关闭模式?如果是后者,您可能需要将prop名称更新为closeModal而不是toggleDisplay.

<div style={{textAlign:"left"}}>
  <CancelIcon style={{ color: "#ff7255" }} onClick={() => this.props.toggleDisplay(false) 
  }/>
</div>        

您的useToggleDisplayfunc 令人困惑,并且原始版本不接受 的任何参数toggleDisplay,因此即使您传入false,它也没有更新display状态。我已经删除useToggleDisplay了,因为它没有做任何特别的事情。

const [display, setDisplay] = useState(initialDisplayState)

我也意识到这<Modal />是接受displayPopUp而不是display. 如果您使用displayPopUp,它不知道display已设置为false,因此保持打开状态。我将setDisplaysetter 传递给<FormLogin />组件。

<Modal className="modal" show={display}  size="lg">
  <Container pose={mode === STATE_LOG_IN ? "signup" : "login"}>
    <div className="container__form container__form--one">
      <FormLogin mode={mode} toggleDisplay={setDisplay} />
     </div>
     <div className="container__form container__form--two">
       <FormSignup mode={mode} toggleDisplay={setDisplay}/>
      </div>
      <Overlay toggleMode={toggleMode} mode={mode} />
   </Container>
 </Modal>

推荐阅读