problem when varying the defaultValue of an input:number reack-hook-form

Advertisements

I am creating a modal window that offers other options to the user to vary quantities through an input and some buttons to increase or decrease the quantity, all this is being handled with the react-hook-form functions.

export const ModalCart = ({ show, id, amount, setHandleConfigModal }) => {
    
    const api = new FormService();
    const { handleSubmit, register, setValue, getValues, formState: { isSubmitting } } = useForm()

    const onSubmit = async (formData) => {
        try {
            console.log({...formData, id})
            setHandleConfigModal({ show: false })
        } catch (e) {
            console.log(e)
        }
    }

    return (
        <Modal
            show={ show }
            onHide={ () => setHandleConfigModal({ show: false }) }
        >
            <Modal.Header closeButton>
                <Modal.Title>Handle the Amount</Modal.Title>
            </Modal.Header>
            
            <Modal.Body>
                <Form onSubmit={ handleSubmit(onSubmit) }>
                    <div className="d-flex gap-2 justify-content-between">
                        <div>
                            <Button
                                className="btn btn-outline-dark px-3 ms-2"
                                disabled={isSubmitting}
                                onClick={ () => setValue( 'amount', Number(getValues('amount')) - 1 ) }
                            >
                                +
                            </Button>
                        </div>

                        <div className="w-100">
                            <Form.Control
                                type="number"
                                placeholder="0"
                                disabled={isSubmitting}
                                defaultValue={ amount}
                                min={0}
                                {...register('amount')}
                            />
                        </div>

                        <div>
                            <Button
                                className="btn btn-outline-dark px-3 me-2"
                                disabled={ isSubmitting }
                                onClick={ () => setValue( 'amount', Number(getValues('amount')) + 1 ) }
                            >
                                -
                            </Button>
                        </div>
                    </div>

                    <Button 
                        disabled={ isSubmitting }
                        type="submit"
                        className="btn btn-primary px-3 me-2 mt-2"
                    > 
                        Save
                    </Button>
                </Form>
            </Modal.Body>
        </Modal>
    );
}

first shipment: amount = 15

output submit
{ amount:15, id:2 }

first shipment: the amount should be = 2

output submit expected
{ amount:2, id:2 }

output submit received
{ amount:15, id:2 }

The problem I have is that when sending the first quantity to the modal through the props, it is correctly assigned to the input, but after sending another quantity again, the input stays with the previous value. If someone could help me with this problem, I am Newbie would appreciate your help.

>Solution :

It seems that the issue you’re experiencing is due to the way React Hook Form handles the input value. When you send a new value to the modal, it doesn’t update the input field because React Hook Form doesn’t automatically update the value when props change. To handle this situation, you can use the useEffect hook to watch for changes in the amount prop and update the input value accordingly.

Here’s the updated version of your ModalCart component with the changes:

import React, { useEffect } from 'react';
import { Modal, Form, Button } from 'react-bootstrap';
import { useForm } from 'react-hook-form';

export const ModalCart = ({ show, id, amount, setHandleConfigModal }) => {
  const { handleSubmit, register, setValue, getValues, formState: { isSubmitting } } = useForm();

  useEffect(() => {
    setValue('amount', amount);
  }, [amount, setValue]);

  const onSubmit = async (formData) => {
    try {
      console.log({ ...formData, id });
      setHandleConfigModal({ show: false });
    } catch (e) {
      console.log(e);
    }
  };

  return (
    <Modal
      show={show}
      onHide={() => setHandleConfigModal({ show: false })}
    >
      <Modal.Header closeButton>
        <Modal.Title>Handle the Amount</Modal.Title>
      </Modal.Header>

      <Modal.Body>
        <Form onSubmit={handleSubmit(onSubmit)}>
          <div className="d-flex gap-2 justify-content-between">
            <div>
              <Button
                className="btn btn-outline-dark px-3 ms-2"
                disabled={isSubmitting}
                onClick={() => setValue('amount', Number(getValues('amount')) - 1)}
              >
                -
              </Button>
            </div>

            <div className="w-100">
              <Form.Control
                type="number"
                placeholder="0"
                disabled={isSubmitting}
                defaultValue={amount}
                min={0}
                {...register('amount')}
              />
            </div>

            <div>
              <Button
                className="btn btn-outline-dark px-3 me-2"
                disabled={isSubmitting}
                onClick={() => setValue('amount', Number(getValues('amount')) + 1)}
              >
                +
              </Button>
            </div>
          </div>

          <Button
            disabled={isSubmitting}
            type="submit"
            className="btn btn-primary px-3 me-2 mt-2"
          >
            Save
          </Button>
        </Form>
      </Modal.Body>
    </Modal>
  );
};

I added the import for useEffect at the beginning of your code and used useEffect to watch for changes in the amount prop. When the amount prop changes, the input value will be updated accordingly using the setValue function from React Hook Form.

Please note that I also corrected the +/- button labels to properly represent their respective actions.

Leave a ReplyCancel reply