Conditional onclick funtion firing without click?

Viewed 649

I have set up a conditional element on click on a button I've made within react. but default prop runs onload without clicking the button how can I fix this issue?

the button looks like this:

<p onClick={Butter + Milk + Bread + Soup + Cheese > 0 ? props.next_ClickHandler : alert('Please Input some food!')}>Buy Now!</p>

I would like it so that if the values add to greater than 0 the props are passed but if not an alert is played why it this not working as intended?

Edit full code:

import React, { useState, useEffect, useContext } from "react";
import Data from '../shoppingData/Ingredients';
import { quantitiesContext } from '../shoppingData/Quantities';

const ShoppingPageOne = (props) => {

  //element displays
  const [pageone_show, setPageone_show] = useState("pageOne");

  //stores quantities of items as JSON objects
  const [Quantities, setQuantities] = useContext(quantitiesContext);

  const quantities = useContext(quantitiesContext);

  const Bread = quantities[0].Bread.quantities;
  const Milk = quantities[0].Milk.quantities;
  const Cheese = quantities[0].Cheese.quantities;
  const Soup = quantities[0].Soup.quantities;
  const Butter = quantities[0].Butter.quantities;

  useEffect(() => {
    //sets info text using Json
    if (props.showOne) {
      setPageone_show("pageOne");
    } else {
      setPageone_show("pageOne hide");
    }
  }, [props.showOne]);


  return (
    <div className={"Shopping_Content " + pageone_show}>


      <div className="Shopping_input_aligner">
        <div className='Shopping_input_container'>
          {Data.map((Ingredients) => {

            //updates Quanties Hook
            const handleChange = (event) => {

              setQuantities({
                ...Quantities,
                [Ingredients.Name]: {
                  ...(Quantities[Ingredients.Name] ?? {}),
                  quantities: event.target.value
                }
              });
            };

            return (<div className={"Shopping_input " + Ingredients.Name} key={Ingredients.Name}>
              <p>{Ingredients.Name} £{Ingredients.Price}</p>
              <input onChange={handleChange.bind(this)} min="0" placeholder="Input food quantity" type="number"></input>
            </div>)
          })}
        </div>

        <div className='Discount_list'>
          <h3>Discounts:</h3>
          <li>Buy one cheese get one free!</li>
          <li>Buy a Soup get a half price bread!</li>
          <li>A third off butter!</li>
        </div>
      </div>
      <div className="Shopping_Buttons">
        <p onClick={() => {Butter + Milk + Bread + Soup + Cheese > 0 ? props.next_ClickHandler : alert('Please Input some food!')}} >Buy Now!</p>
      </div>

    </div>
  );
};

export default ShoppingPageOne;
3 Answers

You can have a cleaner code with something like this if you're using React Hooks

const [ingredientsGreaterThanZero, setIngredientsGreaterThanZero] = useState(false);

useEffect(() => {
  if (butter + milk + bread + soup + cheese > 0) {
    setIngredientsGreaterThanZero(true)
  } else {
    setIngredientsGreaterThanZero(false)
  }
}, [butter, milk, bread, soup, cheese]);

...

{ingredientsGreaterThanZero ? 
  <p onClick={props.next_ClickHandler}>Buy Now!</p> :
  <p onClick={() => alert('Please Input some food!')}>Buy Now!</p>
}
<p onClick={() => { Butter + Milk + Bread + Soup + Cheese > 0 ? props.next_ClickHandler : alert('Please Input some food!')}}>Buy Now!</p>

Can you try using this?

Reason

If you attach any event in element with onClick() or any other event handler,
You shouldn't add any function invocation like in your example alert().
Because, of parentheses () the function runs when component mounted in dom.

Example:

<p onClick={alert('runs on load')}>wrong way</p>

Solution
You have to add an empty function and and writes your codes in it. If your codes contain function invocation ( with parentheses () ).

Example:
<p onClick={() => alert ('only runs on click')}>right way</p>

Happy Coding :)

Related