简体   繁体   中英

How do I check to make sure the form is filled on button click in React?

I have a button that does a calculation based on the numbers provided by the user and populates the result to the page. That same button also saves the product to a database while also visually populating the page with those same products from the database. So basically it shows the total and the previous totals from whatever the user input into the fields. My issue is that I want to include error handling so that if the number is either 0 or NaN because they didn't fill all the forms, it would throw an alert and also not push the data to the database. This was my attempt and it does not work, if the result is NaN it still displays it and pushes the NaN value to the database, how do I achieve this? Attempt is bellow:

handleClick = (event, billInfo) => {
event.preventDefault();
const dbRef = firebase.database().ref();

const result =
  (billInfo.amount / billInfo.group) * (billInfo.tip / 100 + 1);

// ATTEMPT START ======

result === NaN
  ? alert("Please fill all forms!")
  : dbRef.push({
      result: result.toFixed(2),
      name: billInfo.name,
    });

// ATTEMPT END ======

this.setState({
  total: result.toFixed(2),
});

This is the form component with the button that links to the main app.js:

class inputForm extends Component {
  constructor() {
    super();
    this.state = {
      name: "",
      group: "",
      amount: "",
      tip: "",
    };
  }

  handleChange = (event) => {
    this.setState({
      [event.target.name]: event.target.value,
    });
  };

  clearForm = (event) => {
    event.preventDefault();

    this.setState({
      name: "",
      group: "",
      amount: "",
      tip: "",
    });
  };

  render() {
    return (
      <form className="tipApp">
        <div>
          <label htmlFor="groupName">
            <i class="fas fa-id-card"></i>Group Name?
          </label>
          <input
            onChange={this.handleChange}
            type="text"
            id="groupName"
            value={this.state.name}
            placeholder="Name your group"
            name="name"
          />
        </div>

        <div>
          <label htmlFor="groupSize">
            <i class="fas fa-users"></i>How many?
          </label>
          <input
            onChange={this.handleChange}
            type="number"
            id="groupSize"
            value={this.state.group}
            min="1"
            step="1"
            placeholder="Add the group size"
            name="group"
            required
          />
        </div>

        <div>
          <label htmlFor="billAmount">
            <i class="fas fa-receipt"></i>How much?
          </label>
          <input
            onChange={this.handleChange}
            type="number"
            id="billAmount"
            value={this.state.amount}
            min="0"
            step=".01"
            placeholder="Add the bill total"
            name="amount"
            required
          />
        </div>

        <div>
          <label htmlFor="tipAmount">
            <i class="fas fa-heart"></i>Tip?
          </label>
          <input
            onChange={this.handleChange}
            type="number"
            id="tipAmount"
            value={this.state.tip}
            min="10"
            step="5"
            placeholder="Add the tip %"
            name="tip"
          />
        </div>

        <button onClick={(event) => this.props.getTotal(event, this.state)}>
          Split it!
        </button>
        <button onClick={this.clearForm}>Reset</button>
      </form>
    );
  }
}

This is the full app.js main file that I attempted to error handle on:

class App extends Component {
  constructor() {
    super();
    this.state = {
      bills: [],
      total: 0,
    };
  }

  componentDidMount() {
    const dbRef = firebase.database().ref();

    // Event listener that watches the database
    dbRef.on("value", (snapshot) => {
      const firebaseData = snapshot.val();

      const billData = [];

      for (const bill in firebaseData) {
        billData.push({
          id: bill,
          name: firebaseData[bill].name,
          value: firebaseData[bill].result,
        });
      }
      this.setState({
        bills: billData,
      });
    });
  }

  handleClick = (event, billInfo) => {
    event.preventDefault();
    const dbRef = firebase.database().ref();

    const result =
      (billInfo.amount / billInfo.group) * (billInfo.tip / 100 + 1);

    result === NaN
      ? alert("Please fill all forms!")
      : dbRef.push({
          result: result.toFixed(2),
          name: billInfo.name,
        });

    this.setState({
      total: result.toFixed(2),
    });
  };

  deleteBill = (billId) => {
    const dbRef = firebase.database().ref();

    dbRef.child(billId).remove();
  };

  render() {
    return (
      <div className="wrapper">
        <h1 className="logoName">Spl|tr</h1>
        <h3>Bill Splitting App</h3>

        <Form getTotal={this.handleClick} />
        <h2>${this.state.total}</h2>

        <h3>Previous Bills</h3>
        <Bills receipts={this.state.bills} delete={this.deleteBill} />
      </div>
    );
  }
}

And this is the Bills.js component that populated the page with the previous items below the form on button click:

const Bills = (props) => {
  return (
    <ul>
      {props.receipts.map((bill) => {
        return (
          <li key={bill.id}>
            <p>{bill.name}</p>
            <p>${bill.value}</p>
            <button onClick={() => props.delete(bill.id)}>
              <i class="fas fa-times-circle"></i>
            </button>
          </li>
        );
      })}
    </ul>
  );
};

Your handler updates state regardless of valid result or not. A small refactor should allow either a valid result and push to DB and update state OR an invalid result and alert. Both 0 and NaN are falsey values, so you can simply check if result is truthy/falsey.

handleClick = (event, billInfo) => {
  event.preventDefault();
  const dbRef = firebase.database().ref();

  const result =
    (billInfo.amount / billInfo.group) * (billInfo.tip / 100 + 1);

  if (result) {
    dbRef.push({
      result: result.toFixed(2),
      name: billInfo.name,
    });
    this.setState({
      total: result.toFixed(2),
    });
  } else {
    alert("Please fill all forms!")
  }
};

编辑 how-do-i-check-to-make-sure-the-form-is-filled-on-button-click-in-react

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM