У меня есть эта кнопка здесь

   <button className={Classes.Button}
    disabled={!isEnabled}
    type="submit">
        {buttonText}
    </button>

Который должен быть отключен или включен после проверки значения некоторых из моих входов. условия

 const canBeSubmitted = () => {
    return (
      costumerData.firstNameState.length > 0 && // TextInput
      costumerData.emailState.length > 0 && // TextInput
      costumerData.companeyState.length > 0 && // TextInput
      costumerData.selected.length > 0 &&   // Dropdown
      costumerData.agree === true // checkbox for terms
    );
  };
  let isEnabled = canBeSubmitted();

BTW: флажок согласия установлен его обработчиком и работает нормально. Согласованное значение false в состоянии и обработчике

 const handleChange = (event) => {
    const field = event.target.id;
    if (field === "firstName") {
      setFirstName({ firstName: event.target.value });
    } else if (field === "email") {
      setEmail({ email: event.target.value });
    } else if (field === "country") {
      setSelected({ country: event.target.value });
    } else if (field === "agree") {
      setAgree(!agree);
      console.log(agree);
    }
  };

Но всегда возвращает false. что мне не хватает? пожалуйста, помогите мне

2
Harry9345 11 Фев 2021 в 11:14

2 ответа

Лучший ответ

Если я прав, ваше «состояние» не меняется из-за того, как вы меняете «переменные состояния» в функции жирной стрелки handleChange.
Я могу ошибаться в зависимости от того, как устроено ваше «состояние».

Я предполагаю, что ваше «состояние» структурировано следующим образом.

const [firstName, setFirstName] = useState("");
const [email, setEmail] = useState("");
const [country, setCountry] = useState("");
const [agree, setAgree] = useState(false);    
  1. Исправьте вашу функцию handleChange.
// Commented out your possibly erroneous code.
const handleChange = (event) => {
    const field = event.target.id;

    if (field === "firstName") {
        // Fix here.
        // setFirstName({ firstName: event.target.value }); ❌
        setFirstName(event.target.value); ✅
    } else if (field === "email") {
        // Fix here.
        // setEmail({ email: event.target.value }); ❌
        setEmail(event.target.value); ✅
    } else if (field === "country") {
        // Fix here.
        // setSelected({ country: event.target.value }); ❌
        setCountry(event.target.value); ✅
    } else if (field === "agree") {
        // Fix here.
        // setAgree(!agree); ❌
        setAgree(event.target.checked); ✅
        console.log(agree);
    }
};
  1. Затем вы можете выполнить свою проверку следующим образом:
const canBeSubmitted = () => {
    return (
    firstName.trim().length && // TextInput
    email.trim().length && // TextInput
    country.trim().length && // Dropdown
    agree // checkbox for terms
    );
};
  1. Похоже, у вас также есть опечатка для 'countryState':
costumerData.companeyState.length > 0 && // TextInput
  1. Похоже, что в вашем коде после оператора && стоит точка.
costumerData.selected.length > 0 &&.   // Dropdown

Дополнение

@ Harry9345, ты можешь полностью избавиться от handleChange.

Полный исходный код ниже . Демо: https: // codeandbox.io/s/crimson-fog-vp19s?file=/src/App.js

import { useEffect, useState } from "react";

export default function App() {
  const [firstName, setFirstName] = useState("");
  const [email, setEmail] = useState("");
  const [country, setCountry] = useState("");
  const [agree, setAgree] = useState(false);

  const canBeSubmitted = () => {
    const isValid =
      firstName.trim().length && // TextInput
      email.trim().length && // TextInput
      country.trim().length && // Dropdown
      agree; // checkbox for terms

    if (isValid) {
      document.getElementById("submitButton").removeAttribute("disabled");
    } else {
      document.getElementById("submitButton").setAttribute("disabled", true);
    }
    console.log({ firstName, email, country, agree });
  };

  useEffect(() => canBeSubmitted());

  return (
    <div>
      <form action="" method="post" id="form">
        <label htmlFor="firstName">First name:</label>
        <br />
        <input
          type="text"
          id="firstName"
          name="firstName"
          value={firstName}
          onChange={(e) => setFirstName(e.target.value)}
        />
        <br />
        <label htmlFor="email">Email Address:</label>
        <br />
        <input
          type="email"
          id="email"
          name="email"
          value={email}
          onChange={(e) => setEmail(e.target.value)}
        />
        <br />
        <label htmlFor="country">Choose a country:</label>
        <br />
        <select
          id="country"
          name="country"
          value={country}
          onChange={(e) => setCountry(e.target.value)}
        >
          <option value="">Select..</option>
          <option value="1">USA</option>
          <option value="2">Canada</option>
          <option value="3">Algeria</option>
        </select>
        <br />
        <input
          type="checkbox"
          name="agree"
          id="agree"
          onClick={(e) => setAgree(e.target.checked)}
        />
        <label> I agree.</label>
        <br />
        <button type="submit" id="submitButton">
          Submit
        </button>
      </form>
    </div>
  );
}

0
steven7mwesigwa 11 Фев 2021 в 17:55

Вы должны использовать состояние вместо переменной:

Я добавил пример:

import { useState } from "react";

const App = () => {
  const [isDisabled, setIsDisabled] = useState(true);
  const [checked, setChecked] = useState(false);

  const canBeSubmitted = () => {
    return checked ? setIsDisabled(true) : setIsDisabled(false);
  };

  const onCheckboxClick = () => {
    setChecked(!checked);
    return canBeSubmitted();
  };

  return (
    <div className="App">
      <input type="checkbox" onClick={onCheckboxClick} />
      <button type="submit" disabled={isDisabled}>
        Submit
      </button>
    </div>
  );
};

export default App;

codesandbox

Конечно, это всего лишь образец кода, и он не очень эффективен.

0
Uria Levi 11 Фев 2021 в 09:56
66150993