【问题标题】:React : How to make password characters visible when typing each character and hide(*) after few time interval in react?反应:如何在输入每个字符时使密码字符可见,并在反应的几个时间间隔后隐藏(*)?
【发布时间】:2020-04-07 11:31:12
【问题描述】:

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

我发现使用 jQuery 的解决方案很少,并尝试将其转换为 react,但它的行为与 react 不同,因为有一个 setState 会延迟设置值。这是我的反应代码,它的行为不一致。

    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

我们将不胜感激。

【问题讨论】:

    标签: javascript jquery reactjs formik


    【解决方案1】:

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

    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>

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

    【讨论】:

    • 感谢您的所有努力!我期望的情况与此相反,我希望我输入字符的字段应该隐藏在类型上,但这里另一个字段是星号。最后一个字符仍然可见
    • 刚刚意识到可能是图像让您感到困惑。我想在一秒钟后隐藏最后一个字符。
    • @PratikN 我仍然不能 100% 确定你想要什么,但这里有另一个版本可以给你一个好的开始。编码愉快。
    • 再次感谢。如果有帮助,你能看到这个链接stackoverflow.com/questions/37186309/…吗?
    【解决方案2】:

    我发现解决方案唯一的错误是在 onChange 中设置和调用 setTimeout,因此它永远不会取消/清除实际的 setTimeout

    解决办法

    const styles = {
      facebookBtn: {
        backgroundColor: "rgb(51, 89, 157)"
      },
      form: {
        textAlign: "center"
      }
    };
    
    class Login extends React.Component {
      constructor(props) {
        super(props);
        this.hideAll = setTimeout(() => {}, 0);
    
        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 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(this.hideAll);
        this.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"));
    <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>

    【讨论】:

      猜你喜欢
      • 2020-02-15
      • 2021-09-21
      • 2023-02-25
      • 1970-01-01
      • 2022-07-21
      • 2017-07-06
      • 2021-04-16
      • 2011-12-06
      相关资源
      最近更新 更多