Как включать/отключать disabled в <form> и сохранять результат без перерендера?

Рейтинг: 0Ответов: 1Опубликовано: 07.08.2023

Есть форма с 3 полями, средняя форма Email по-умолчанию disabled через стейт. Есть кнопка Open/Close Input, которая должна в реал-тайм менять её состояние с true на false и наоборот. Через стейт не получается, т.к. стейт по клику измениться компонент переинициализируется и inputDisabled будет снова true. Через refтоже пробовал, не получается, т.к. ref вообще не изменить не получается. Помогите)


export function Form() {
  const [name, setName] = useState("");
  const [email, setEmail] = useState("");
  const [phone, setPhone] = useState("");
  const [inputDisabled, setInputDisabled] = useState(true);

  console.log("pererender");

  function handleNameChange(event) {
    setName(event.target.value);
  }
  function handleEmailChange(event) {
    setEmail(event.target.value);
  }
  function handlePhoneChange(event) {
    setPhone(event.target.value);
  }

  const inputOpen = () => {
    setInputDisabled((prev) => !prev);
  };

  function handleSubmit() {
    console.log({
      name,
      email,
      phone,
    });
  }

  return (
    <form className="form__main-container">
      <div className="form__input-container">
        <label htmlFor="name">Name:</label>
        <input type="text" id="name" name="name" onChange={handleNameChange} />
      </div>
      <div className="form__input-container">
        <label htmlFor="email">Email:</label>
        <input
          type="text"
          id="email"
          name="email"
          onChange={handleEmailChange}
          disabled={inputDisabled}
        />
      </div>
      <div className="form__input-container">
        <label htmlFor="phone">Phone:</label>
        <input
          type="text"
          id="phone"
          name="phone"
          onChange={handlePhoneChange}
        />
      </div>
      <button type="button" onClick={handleSubmit}>
        Submit
      </button>
      <button onClick={() => inputOpen()}>Open/Close Input</button>
    </form>
  );
}

Ответы

▲ 0Принят

Через стейт не получается, т.к. стейт по клику измениться компонент переинициализируется

Как вариант - добавить соответствующей кнопке "простой" тип type='button'...

//
function Form() {
  const [name, setName] = React.useState("");
  const [email, setEmail] = React.useState("");
  const [phone, setPhone] = React.useState("");
  const [inputDisabled, setInputDisabled] = React.useState(true);

  function handleNameChange(event) {
    setName(event.target.value);
  }
  function handleEmailChange(event) {
    setEmail(event.target.value);
  }
  function handlePhoneChange(event) {
    setPhone(event.target.value);
  }

  const inputOpen = () => {
    setInputDisabled(prev => !prev);
  };

  function handleSubmit() {
    console.log({
      name,
      email,
      phone,
    });
  }

  return (
    <form className="form__main-container">
      <div className="form__input-container">
        <label htmlFor="name">Name:</label>
        <input type="text" id="name" name="name" onChange={handleNameChange} />
      </div>
      <div className="form__input-container">
        <label htmlFor="email">Email:</label>
        <input
          type="text"
          id="email"
          name="email"
          onChange={handleEmailChange}
          disabled={inputDisabled}
        />
      </div>
      <div className="form__input-container">
        <label htmlFor="phone">Phone:</label>
        <input
          type="text"
          id="phone"
          name="phone"
          onChange={handlePhoneChange}
        />
      </div>
      <button type="button" onClick={handleSubmit}>
        Submit
      </button>
      <button type='button' onClick={inputOpen}>Open/Close Input</button>
    </form>
  );
}
const domContainer = document.querySelector('#like_button_container');
const root = ReactDOM.createRoot(domContainer);
root.render(<Form />);
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<div id="like_button_container"></div>