javascriptreactjsbuttonuse-refdisabled-control

How can I disable the button at the end of this component?


import { useRef, useState } from 'react'    
import Input from '../../UI/Input'

import classes from './MealItemForm.module.css'

export default function MealItemForm(props) {
  const [amountIsValid, setAmountIsValid] = useState(true)

  const amountInputRef = useRef()

  const submitHandler = event => {
    event.preventDefault()

    const enteredAmount = amountInputRef.current.value
    const enteredAmountNumber = +enteredAmount

    if (enteredAmount.trim().length === 0 || enteredAmountNumber < 1 || enteredAmountNumber > 20) {
      setAmountIsValid(false)
      return
    }

    props.onAddToCart(enteredAmountNumber)
  }

Tried to add a function after submitHandler to disabled the button when the enteredAmountNumber > 20, but couldn't make it working!

  return (
    <form className={classes.form} onSubmit={submitHandler}>
      <Input
        ref={amountInputRef}
        label='Amount'
        input={{
          id: 'amount_' + props.id,
          type: 'number',
          min: '1',
          max: '20',
          step: '1',
          defaultValue: '1'
        }}
      />
      {/* Two curly braces: one for embedding javascript expression and the other one is there because the value is object */}

I want to disable this button when the enteredAmount > 20, please help me!

      <button>+ Add</button>

      {!amountIsValid && <p>Please enter a valid amount(1~20)</p>}
    </form>
  )
}

Solution

  • You need use disabled attribute of button

    <button disabled={enteredAmountNumber > 20}>Enter Amount</button>
    

    Code based on your comment

    import { useRef, useState } from 'react'    
    import Input from '../../UI/Input'
    
    import classes from './MealItemForm.module.css'
    
    export default function MealItemForm(props) {
      const [amountIsValid, setAmountIsValid] = useState(true)
    
      const amountInputRef = useRef()
    
      const submitHandler = event => {
        event.preventDefault()
    
        const enteredAmount = amountInputRef.current.value
        const enteredAmountNumber = +enteredAmount
    
        if (enteredAmount.trim().length === 0 || enteredAmountNumber < 1 || enteredAmountNumber > 20) {
          setAmountIsValid(false)
          return
        }
    
        props.onAddToCart(enteredAmountNumber)
      }
    
    return (
        <form className={classes.form} onSubmit={submitHandler}>
          <Input
            ref={amountInputRef}
            label='Amount'
            input={{
              id: 'amount_' + props.id,
              type: 'number',
              min: '1',
              max: '20',
              step: '1',
              defaultValue: '1'
            }}
          />
          {/* Two curly braces: one for embedding javascript expression and the other one is there because the value is object */}
    
       <button disabled={!amountIsValid}>+ Add</button>
    
          {!amountIsValid && <p>Please enter a valid amount(1~20)</p>}
        </form>
      )
    }
    

    UPDATE based on your comment

    WORKING DEMO

    Edit #SO-material-onclick-edit

    import "./styles.css";
    import react, { useState } from "react";
    
    export default function App() {
      const [clickCount, setClickCount] = useState(0);
    
      return (
        <div className="App">
          <h1>Hello CodeSandbox</h1>
          <h2>Start editing to see some magic happen!</h2>
          <button
            disabled={clickCount >= 20}
            onClick={() => {
              setClickCount((clickCount) => clickCount + 1);
            }}
          >
            {clickCount === 0 ? `Click Me` : `You clicked ${clickCount} times`}{" "}
          </button>
        </div>
      );
    }