对多个字段做出反应的密码眼睛图标

时间:2019-01-04 14:40:43

标签: reactjs

我有三个密码字段,每个字段都有一个眼睛图标,供消费者显示/隐藏密码,

我正在尝试下面的代码,但是如果我单击一个字段的隐藏/显示,那么它也会影响其他字段。

请指导我纠正下面的代码

class ShowPassword extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      type: 'input',
      score: 'null'
    }
    this.showHide = this.showHide.bind(this);
  }

  showHide(e){
    //e.preventDefault();
    //e.stopPropagation();
    this.setState({
      type: this.state.type === 'input' ? 'password' : 'input'
    })  
  }


  render(){
    return(
      <div>
      <label className="password">Current Password
      <input type={this.state.type} className="password__input"/>
      <span className="password__show" onClick={this.showHide}>{this.state.type === 'input' ? 'Hide' : 'Show'}</span>
      </label>

            <label className="password">New Password
      <input type={this.state.type} className="password__input"/>
      <span className="password__show" onClick={this.showHide}>{this.state.type === 'input' ? 'Hide' : 'Show'}</span>
      </label>

            <label className="password">Confirm Password
      <input type={this.state.type} className="password__input"/>
      <span className="password__show" onClick={this.showHide}>{this.state.type === 'input' ? 'Hide' : 'Show'}</span>
      </label>
        </div>
    )
  }
}

ReactDOM.render(<ShowPassword/>, document.getElementById('react'));

下面是要玩的jsbin链接

https://jsbin.com/homuxoq/edit?html,css,js,output

3 个答案:

答案 0 :(得分:1)

将输入字段提取到其自己的组件中

class PasswordField extends React.Component{
  state = {
    type: 'text',
  }


  handleClick = () => this.setState(({type}) => ({
    type: type === 'text' ? 'password' : 'text'
  }))


  render() {
    const { label } = this.props

    return (
      <label className="password">{label}
        <input type={this.state.type} className="password__input"/>
        <span className="password__show" onClick={this.handleClick}>{this.state.type === 'text' ? 'Hide' : 'Show'}</span>
      </label>
    )
  }
}

Link to JSBin

我想在这里提及的另一件事是,没有input的输入类型。因此,我已将其替换为有效值text

答案 1 :(得分:0)

在设置状态时,所有输入均由您提供给this.state.type的新类型值呈现

对于不希望通过显示/隐藏按钮生效的输入,您应该删除type={this.state.type},只需使用type="password"

答案 2 :(得分:0)

您的每个密码字段都应具有自己的状态,如果它们被隐藏或显示,则它们包含布尔污点。为避免代码重复,请为您的密码创建一个组件。

工作示例:

class ShowPassword extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            score: 'null'
        }
    }

    render() {
        return (
            <div>
                <PasswordField title='Current Password'/>
                <PasswordField title='New Password' />
                <PasswordField title='Confirm Password' />
            </div>
        )
    }
}

class PasswordField extends React.Component {
    constructor(props) {
        super(props)

        this.state = {
            hide: true
        }
    }

    hideSwitch = ev => {
        this.setState({ hide: !this.state.hide })
    }

    render() {
        const { title } = this.props
        const { hide } = this.state
        return (
            <label className="password">{title}
                <input type={hide ? 'password' : 'input'} className="password__input" />
                <span className="password__show" onClick={this.hideSwitch}>{hide ? 'Show' : 'Hide'}</span>
            </label>
        )
    }
}

ReactDOM.render(<ShowPassword/>, document.getElementById('react'));
$accent: #00BCD4;
$primary: #212121;
$secondary: #727272;

$scoreRed: #F44336;
$scoreYellow: #FFEB3B;
$scoreGreen: #4CAF50;

body, html{
  height: 100%;
}

body{
  background: linear-gradient(#607D8B, #455A64);
  font-family: 'Roboto', sans-serif;
}

form{
  margin: 3em auto;
  max-width: 320px;
  background: #FFFFFF;
  padding: 40px;
  box-shadow: 0 0 20px rgba(0,0,0,.25);
  
}
.password{
  display: block;
  position: relative;
  text-transform: uppercase;
  font-weight: 700;
  width: 100%;
  color: $secondary;
  
  &__input{
    display: block;
    text-transform: none;
    width: 100%;
    height: 42px;
    border-width: 0 0 1px;
    border-style: solid;
    border-color: #B6B6B6;
    font-weight: 400;
    color: $primary;
    
    &:focus, &:active{
      border-color: $accent;
      outline: 0;
    }
  }
  
  &__show{
    cursor: pointer;
    position: absolute;
    bottom: 11px;
    height: 16px;
    right: 0;
    background: $secondary;
    color: white;
    padding: 4px 8px;
    border-radius: 4px;
    font-weight: 700;
    font-size: .8em;
  }
  
  &__strength{
    position: absolute;
    width: 0%;
    height: 4px;
    bottom: -8px;
    left: 0;
    background: transparent;
    transition: all 300ms ease-in-out;
    
    &[data-score="null"]{
      width: 0;
      background: red;
    }
    
    &[data-score="0"]{
      width: 5%;
      background: $scoreRed;
    }
    &[data-score="1"]{
      width: 25%;
      background: $scoreRed;
    }
    &[data-score="2"]{
      width: 50%;
      background: $scoreYellow;
    }
    &[data-score="3"]{
      width: 75%;
      background: $scoreGreen;
    }
    &[data-score="4"]{
      width: 100%;
      background: $scoreGreen;
    }
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.0/umd/react-dom.production.min.js"></script>
<form id="react"></form>