Как зациклиться на нескольких элементах с помощью одного пользователя?

#reactjs

Вопрос:

У меня есть два поля ввода, в которых с помощью одного имени пользователя я хочу получить атрибут current.get для перехода с типа пароля на тип текста. Но, согласно документам, будет выбран только последний элемент. Я хочу использовать .map для зацикливания на элементах. Я не могу использовать .map для создания элементов, потому что каждый из них должен быть уникальным из-за моей аутентификации.

Код

 const passwordRef = useRef();
const handleShowPassword = (e) => {
    console.log(passwordRef.map((e) => console.log(e))); <--- this coz error of passwordRef.map is not a function
    setShowEye(!showEye);
    const type =
      passwordRef.current.getAttribute('type') === 'password'
        ? 'text'
        : 'password';
    passwordRef.current.setAttribute('type', type);
  };

<div className='form-group w-full relative'>
            <PasswordStrength
              type='password'
              placeholder='Current password'
              name='currentPassword'
              ref={passwordRef}
              border={error amp;amp; error.currentPasswordError ? 'failed' : 'transparent'}
              value={userInfo.currentPassword}
              onChange={handleOnChange}
            />
            {!showEye amp;amp; (
              <FontAwesomeIcon
                icon={faEye}
                className='fill-current text-customRed absolute top-4 right-4'
                onClick={handleShowPassword}
              />
            )}
            <label for='password'>
              {showEye amp;amp; (
                <FontAwesomeIcon
                  icon={faEyeSlash}
                  className='fill-current text-customRed absolute top-4 right-4'
                  onClick={handleShowPassword}
                />
              )}
              {error amp;amp; error.passwordError ? (
                <Notifications type='text-failed' field='password'>
                  <span className='text-xxs absolute -left-0 -bottom--7px fadeIn'>
                    {error.msg}
                  </span>
                </Notifications>
              ) : (
                ''
              )}
            </label>
          </div>
          <div className='form-group w-full relative'>
            <PasswordStrength
              type='password'
              placeholder='New password'
              name='password'
              ref={passwordRef}
              border={error amp;amp; error.passwordError ? 'failed' : 'transparent'}
              value={userInfo.password}
              onChange={handleOnChange}
            />
            <label for='password'>
              {error amp;amp; error.passwordError ? (
                <Notifications type='text-failed' field='password'>
                  <span className='text-xxs absolute -left-0 -bottom--7px fadeIn'>
                    {error.msg}
                  </span>
                </Notifications>
              ) : (
                ''
              )}
            </label>
          </div>
 

Ответ №1:

Короткий ответ: вы не можете. Даже если бы это было возможно , ваши входные данные были жестко type="password" закодированы, поэтому видимость пароля будет сброшена при каждом повторном отправке. Но на самом деле вам даже не нужны рефери.

Поля вашего пароля почти идентичны (по крайней мере, визуально). Таким образом, вы можете извлечь поле пароля в отдельный компонент и повторно использовать его дважды. Преимущество такой перестановки заключается в том, что вы можете создать внутреннее состояние, указывающее, отображается ли введенный пароль в виде текста или скрыт.

 const PasswordField = ({ label, ...props }) => {
  const [visible, setVisible] = React.useState(false)
  
  return (
    <label>
      {label}:{' '}
      <input
        type={visible ? 'text' : 'password'}
        {...props}
      />
      <button onClick={() => setVisible(!visible)}>
        {visible ? 'Hide' : 'Show'}
      </button>
    </label>
  )
}

const App = () => {
  return (
    <div>
      <div>
        <PasswordField label="Old Password" defaultValue="12345" />
      </div>
      <div>
        <PasswordField label="New Password" defaultValue="12345" />
      </div>
    </div>
  )
}
 

Мой фрагмент намеренно упрощен, чтобы продемонстрировать перекомпозицию, о которой я упоминал выше.

 const PasswordField = ({ label, ...props }) => {
  const [visible, setVisible] = React.useState(false)
  
  return (
    <label>
      {label}:{' '}
      <input
        type={visible ? 'text' : 'password'}
        {...props}
      />
      <button onClick={() => setVisible(!visible)}>
        {visible ? 'Hide' : 'Show'}
      </button>
    </label>
  )
}

const App = () => {
  return (
    <div>
      <div>
        <PasswordField label="Old Password" defaultValue="12345" />
      </div>
      <div>
        <PasswordField label="New Password" defaultValue="12345" />
      </div>
    </div>
  )
}

ReactDOM.render(<App />, document.getElementById('root')) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

<div id="root"></div>