javascript - react : How to make password characters visible when typing each character and hide(*) after few time interval in react?

标签 javascript jquery reactjs formik

我希望我的密码字段行为如图所示

enter image description here

我找到了一些使用 jQuery 的解决方案,并尝试将其转换为 React,但它的行为与 React 不同,因为有一个 setState 会延迟设置值。这是我的 React 代码,其行为不一致。

    import React from "react";
    import ReactDOM from "react-dom";

// Example JS object used for CSS styling
const styles = {
  facebookBtn: {
    backgroundColor: "rgb(51, 89, 157)"
  },
  form: {
    textAlign: "center"
  }
};

export class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userName: "",
      password: "",
      passHidden: ""
    };
  }
  handleOnSubmit = e => {
    e.preventDefault();
    console.log("Submitted!");
  };

  onUserNameChange = e => {
    const value = e.target.value;
    this.setState({
      userName: value
    });
  };
  onHiddenPasswordChange = e => {};

  onPasswordChange = e => {
    const passwordValue = e.target.value;
    const hiddenPassValue = this.state.passHidden;

    let showLength = 1;
    let hideAll = setTimeout(() => {}, 0);

    let offset = passwordValue.length - hiddenPassValue.length;

    if (offset > 0) {
      this.setState({
        passHidden:
          hiddenPassValue +
          passwordValue.substring(
            hiddenPassValue.length,
            hiddenPassValue.length + offset
          )
      });
    } else if (offset < 0) {
      this.setState({
        passHidden: hiddenPassValue.substring(
          0,
          hiddenPassValue.length + offset
        )
      });
    }

    // Change the visible string
    if (passwordValue.length > showLength) {
      this.setState({
        password:
          passwordValue
            .substring(0, passwordValue.length - showLength)
            .replace(/./g, "•") +
          passwordValue.substring(
            passwordValue.length - showLength,
            passwordValue.length
          )
      });
    }

    // Set the timer
    clearTimeout(hideAll);
    hideAll = setTimeout(() => {
      this.setState({
        password: passwordValue.replace(/./g, "•")
      });
    }, 1000);
      };

      render() {
         return (
      <form style={styles.form} onSubmit={this.handleOnSubmit}>
        <h4>Welcome Back!</h4>
        <div className="form-group row">
          <input
            className="input"
            value={this.state.userName}
            onChange={this.onUserNameChange}
            type="text"
            placeholder="Email"
          />
        </div>
        <div className="form-group row">
          <input
            className="input"
            value={this.state.password}
            onChange={this.onPasswordChange}
            type="text"
            placeholder="Password"
          />
        </div>

        <div className="form-group row">
          <input
            className="input"
            value={this.state.passHidden}
            onChange={this.onHiddenPasswordChange}
            type="text"
            placeholder="Password"
          />
        </div>
        <div className="form-group row">
          <button className="btn" type="submit">
            Log In
          </button>
        </div>
      </form>
    );
      }
    }

     class Form extends React.Component {
      render() {
        const { children, title } = this.props;
        return (
      <div className="col-md-6 mx-auto">
        <header>
          <h1>{title}</h1>
        </header>
        {children}
      </div>
    );
      }
    }

    ReactDOM.render(<Form children={<Login />} />, document.getElementById("root"));

This is the solution link with jQuery

我们将非常感谢您的帮助。

最佳答案

有很多方法可以做到这一点,但这里有一个:

const styles = {
  facebookBtn: {
    backgroundColor: "rgb(51, 89, 157)"
  },
  form: {
    textAlign: "center"
  }
};

class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      userName: "",
      password: "",
      passHidden: ""
    };
    this.clocks = {};
  }

  handleOnSubmit = e => {
    e.preventDefault();
    console.log("Submitted!");
  };

  getLastIndexChar = string => {
    return string.slice(string.length - 1);
  };

  hideAllChars = fieldName => {
    const value = this.state[fieldName];
    let password = "";
    if (value.length) {
      password = Array(value.length).join("•") + "•";
    }
    this.setState({ [fieldName]: password });
  };

  setFieldClock = fieldName => {
    clearTimeout(this.clocks[fieldName]);
    this.clocks[fieldName] = setTimeout(
      () => this.hideAllChars(fieldName),
      1000
    );
  };

  getTypingHiddenPassword = value => {
    return Array(value.length).join("•") + this.getLastIndexChar(value);
  };

  handlePasswordChanged = (fieldName, value) => {
    this.setFieldClock(fieldName);
    const password = this.getTypingHiddenPassword(value);
    this.setState({ [fieldName]: password });
  };

  inputChange = ({ target: { name, value } }) => {
    switch (name) {
      case "password":
      case "passHidden":
        this.handlePasswordChanged(name, value);
        break;
      default:
        this.setState({ [name]: value });
        break;
    }
  };

  render() {
    return (
      <form style={styles.form} onSubmit={this.handleOnSubmit}>
        <h4>Welcome Back!</h4>
        <div className="form-group row">
          <input
            className="input"
            name="userName"
            value={this.state.userName}
            onChange={this.inputChange}
            type="text"
            placeholder="Email"
          />
        </div>
        <div className="form-group row">
          <input
            className="input"
            name="password"
            value={this.state.password}
            onChange={this.inputChange}
            type="text"
            placeholder="Password"
          />
        </div>

        <div className="form-group row">
          <input
            className="input"
            name="passHidden"
            value={this.state.passHidden}
            onChange={this.inputChange}
            type="text"
            placeholder="Password"
          />
        </div>
        <div className="form-group row">
          <button className="btn" type="submit">
            Log In
          </button>
        </div>
      </form>
    );
  }
}

class Form extends React.Component {
  render() {
    const { children, title } = this.props;
    return (
      <div className="col-md-6 mx-auto">
        <header>
          <h1>{title}</h1>
        </header>
        {children}
      </div>
    );
  }
}

ReactDOM.render(<Form children={<Login />} />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

希望对大家有所帮助,祝大家编码愉快!

关于javascript - react : How to make password characters visible when typing each character and hide(*) after few time interval in react?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59332287/

相关文章:

javascript - 将函数与 JavaScript 组合起来变得更加 'Functional'

javascript - 对 .aspx 和 .html 感到困惑

javascript - 单击另一个 div 区域后如何重置字段?

javascript - 检测浏览器或标签页关闭

javascript - 如何在reactjs中选择默认复选框

reactjs - React 无限循环调度,来自 useReducer 钩子(Hook)

reactjs - 为什么在 Firefox 上 React 热重载会自动打开 Debugger?

javascript - 用户界面路由器返回 : "Cannot GET/page"

javascript - AngularJS 拖放事件监听器不起作用

javascript - 如何使用 <a> 标记内的按钮单击以防止链接被跟踪?