when conditionally rendering an input component getting this error – A component is changing a controlled input to be uncontrolled

When I am editing the campaign and switching the Welcome Message Type from Text to Audio it throws this error – Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component.

Audio component is a file component –

index.js

import {
  Button,
  Card,
  CardBody,
  CardHeader,
  Col,
  Container,
  Row,
} from "reactstrap";
import BreadCrumb from "../../Components/Common/BreadCrumb";
import { Link } from "react-router-dom";
import AddCampaignModal from "./AddCampaignModal";
import { useFormik } from "formik";
import * as Yup from "yup";
import CampaignRemoveModal from "./CampaignRemoveModal";
import {
  getCampaigns,
  createCampaign,
  updateCampaign,
  removeCampaign,
} from "../../slices/Campaigns/thunk";

import { useDispatch } from "react-redux";
import { useSelector } from "react-redux";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { getGateway } from "../../slices/Gateway/thunk";
import Loader from "../../Components/Common/Loader";

const Campaigns = () => {
  const [modal_list, setmodal_list] = useState(false);

  const [modal_delete, setmodal_delete] = useState(false);

  const [loading, setLoading] = useState(false);

  const [isEditingCampaign, setIsEditingCampaign] = useState(false);

  const [listCampaignId, setListCampaignId] = useState(null);

  const [welcomeMessageAudio, setWelcomeMessageAudio] = useState("");

  const [invalidMessageAudio, setInvalidMessageAudio] = useState(null);

  const [timeOutMessageAudio, setTimeOutMessageAudio] = useState(null);

  const [selectSingleWelcomeTextOrAudio, setSelectSingleWelcomeTextOrAudio] =
    useState(null);

  const [selectSingleInvalidTextOrAudio, setSelectSingleInvalidTextOrAudio] =
    useState(null);

  const [selectSingleTimeOutTextOrAudio, setSelectSingleTimeOutTextOrAudio] =
    useState(null);

  const [selectedSingleGateway, setSelectedSingleGateway] = useState(null);

  const dispatch = useDispatch();

  const { campaigns, alreadyRegisteredError } = useSelector(
    (state) => state.Campaigns
  );
  const { gateways } = useSelector((state) => state.Gateways);

  function tog_list() {
    setmodal_list(!modal_list);
  }

  function tog_delete() {
    setmodal_delete(!modal_delete);
  }

  useEffect(() => {
    if (alreadyRegisteredError) {
      setmodal_list(!modal_list);
    }
  }, [alreadyRegisteredError]);

  useEffect(() => {
    setLoading(true);
    dispatch(getCampaigns()).finally(() => {
      setLoading(false);
    });
    dispatch(getGateway());
  }, [dispatch]);

  const welcomeMessageTextOrAudioOptions = [
    { label: "Text", value: "Text" },
    { label: "Audio", value: "Audio" },
  ];

  function handleSelectSingleWelcomeMessageTextOrAudio(welcomeMessageType) {
    setSelectSingleWelcomeTextOrAudio(welcomeMessageType);
    // if (welcomeMessageType?.value === "Audio") {
    //   validation.setFieldValue("welcomeMessageText", "");
    // }
  }
  const invalidMessageTextOrAudioOptions = [
    { label: "Text", value: "Text" },
    { label: "Audio", value: "Audio" },
  ];

  function handleSelectSingleInvalidMessageTextOrAudio(invalidMessageType) {
    setSelectSingleInvalidTextOrAudio(invalidMessageType);
  }
  const timeOutMessageTextOrAudioOptions = [
    { label: "Text", value: "Text" },
    { label: "Audio", value: "Audio" },
  ];

  function handleSelectSingleTimeOutMessageTextOrAudio(timeOutMessageType) {
    setSelectSingleTimeOutTextOrAudio(timeOutMessageType);
  }

  const gatewayOptions = gateways?.map((gateway) => {
    return {
      id: gateway.id,
      value: gateway.gatewayIpAddress,
      label: gateway.gatewayIpAddress,
    };
  });

  function handleSelectSingleGateway(gateway) {
    setSelectedSingleGateway(gateway);
  }

  const validation = useFormik({
    initialValues: {
      campaignName: "",
      gatewayId: "",
      welcomeMessageText: "",
      InvalidMessageText: "",
      timeOutMessageText: "",
    },
    validationSchema: Yup.object({
      campaignName: Yup.string().required("Please enter campaign name"),
      gatewayId: Yup.string().required("Gateway is required"),
      welcomeMessageText: Yup.string(),
      invalidMessageText: Yup.string(),
      timeOutMessageText: Yup.string(),
    }),
    onSubmit: (values, { resetForm }) => {
      if (isEditingCampaign) {
        dispatch(
          updateCampaign({
            ...values,
            campaignId: listCampaignId,
            welcomeMessageAudio,
            invalidMessageAudio,
            timeOutMessageAudio,
            gatewayId: selectedSingleGateway.id,
          })
        );
      } else {
        dispatch(
          createCampaign({
            ...values,
            welcomeMessageAudio,
            invalidMessageAudio,
            timeOutMessageAudio,
            gatewayId: selectedSingleGateway.id,
          })
        );
      }

      // if (!isEditingCampaign) {
      //   resetForm();
      // }

      resetForm();

      setSelectedSingleGateway(null);
      setSelectSingleInvalidTextOrAudio(null);
      setSelectSingleTimeOutTextOrAudio(null);
      setSelectSingleWelcomeTextOrAudio(null);

      setmodal_list(false);
    },
  });

  console.log("VALIDATION VALUES ->", validation.values);

  function formHandleSubmit(e) {
    e.preventDefault();
    validation.handleSubmit();

    if (!validation.errors) {
      setmodal_list(false);
    }
    return false;
  }

  function handleEditCampaign(campaignData) {
    setIsEditingCampaign(true);
    setmodal_list(!modal_list);
    setListCampaignId(campaignData.id);

    const selectedGateway = gatewayOptions?.find(
      (gateway) => (gateway.id = campaignData.gatewayId)
    );

    if (campaignData.welcomeMessageText) {
      const selectedOption = welcomeMessageTextOrAudioOptions.find(
        (option) => option.value === "Text"
      );

      setSelectSingleWelcomeTextOrAudio(selectedOption);
    } else {
      validation.setFieldValue("welcomeMessageText", ""); // Ensure welcomeMessageText is cleared
    }

    if (campaignData.invalidMessageText) {
      const selectedOption = invalidMessageTextOrAudioOptions.find(
        (option) => option.value === "Text"
      );

      setSelectSingleInvalidTextOrAudio(selectedOption);
    }
    if (campaignData.timeOutMessageText) {
      const selectedOption = timeOutMessageTextOrAudioOptions.find(
        (option) => option.value === "Text"
      );

      setSelectSingleTimeOutTextOrAudio(selectedOption);
    }

    setSelectedSingleGateway(selectedGateway);

    validation.setValues({
      campaignName: campaignData.campaignName,
      welcomeMessageText: campaignData.welcomeMessageText,
      invalidMessageText: campaignData.invalidMessageText,
      timeOutMessageText: campaignData.timeOutMessageText,
      gatewayId: campaignData.gatewayId,
    });
  }

  function tog_list() {
    validation.resetForm();
    setSelectedSingleGateway(null);
    setSelectSingleInvalidTextOrAudio(null);
    setSelectSingleTimeOutTextOrAudio(null);
    setSelectSingleWelcomeTextOrAudio(null);

    setmodal_list(!modal_list);
  }

  document.title = "Campaigns";
  return (
    <React.Fragment>
      <div className="page-content">
        <Container fluid>
          <BreadCrumb title="Campaigns" pageTitle="Management" />
          <Row>
            <Col lg={12}>
              <Card>
                <CardHeader>
                  <h4 className="card-title mb-0">Create a Campaign</h4>
                </CardHeader>

                <CardBody>
                  <div className="listjs-table" id="userList">
                    <Row className="g-4 mb-3">
                      <Col className="col-sm-auto w-100 d-flex justify-content-between">
                        <Button
                          color="primary"
                          className="add-btn me-1"
                          onClick={tog_list}
                          id="create-btn"
                        >
                          <i className="ri-add-line align-bottom me-1"></i> Add
                          Campaign
                        </Button>
                      </Col>
                    </Row>

                    <div className="table-responsive table-card mt-3 mb-1">
                      <table
                        className="table align-middle table-nowrap"
                        id="userTable"
                      >
                        <thead className="table-light">
                          <tr>
                            <th>S.No</th>
                            <th>Campaign Name</th>
                            <th>Welcome Text</th>
                            <th>Invalid Text</th>
                            <th>TimeOut Text</th>

                            <th>Action</th>
                          </tr>
                        </thead>
                        <tbody className="list form-check-all">
                          {loading ? (
                            <tr>
                              <td
                                colSpan={7}
                                style={{
                                  border: "none",
                                  textAlign: "center",
                                  verticalAlign: "middle",
                                }}
                              >
                                <Loader />
                              </td>
                            </tr>
                          ) : (
                            <>
                              {campaigns?.map((campaign, idx) => (
                                <tr key={campaign.id}>
                                  <td>{idx + 1}</td>
                                  <td>{campaign.campaignName}</td>
                                  <td>{campaign.welcomeMessageText}</td>
                                  <td>{campaign.invalidMessageText}</td>
                                  <td>{campaign.timeOutMessageText}</td>

                                  <td>
                                    <div className="d-flex gap-2">
                                      <div className="edit">
                                        <button
                                          className="btn btn-sm btn-primary edit-item-btn"
                                          data-bs-toggle="modal"
                                          data-bs-target="#showModal"
                                          onClick={() => {
                                            handleEditCampaign(campaign);
                                          }}
                                        >
                                          Edit
                                        </button>
                                      </div>

                                      <div className="remove">
                                        <button
                                          className="btn btn-sm btn-danger edit-item-btn"
                                          data-bs-toggle="modal"
                                          data-bs-target="#showModal"
                                          onClick={() => {
                                            setListCampaignId(campaign.id);
                                            tog_delete();
                                          }}
                                        >
                                          Remove
                                        </button>
                                      </div>
                                    </div>
                                  </td>
                                </tr>
                              ))}
                            </>
                          )}
                        </tbody>
                      </table>
                    </div>

                    <div className="d-flex justify-content-end">
                      <div className="pagination-wrap hstack gap-2">
                        <Link
                          className="page-item pagination-prev disabled"
                          to="#"
                        >
                          Previous
                        </Link>
                        <ul className="pagination listjs-pagination mb-0"></ul>
                        <Link className="page-item pagination-next" to="#">
                          Next
                        </Link>
                      </div>
                    </div>
                  </div>
                </CardBody>
              </Card>
            </Col>
          </Row>
        </Container>
      </div>
      <ToastContainer />

      <AddCampaignModal
        validation={validation}
        isEditingCampaign={isEditingCampaign}
        modal_list={modal_list}
        tog_list={tog_list}
        formHandleSubmit={formHandleSubmit}
        alreadyRegisteredError={alreadyRegisteredError}
        welcomeMessageAudio={welcomeMessageAudio}
        setWelcomeMessageAudio={setWelcomeMessageAudio}
        invalidMessageAudio={invalidMessageAudio}
        setInvalidMessageAudio={setInvalidMessageAudio}
        timeOutMessageAudio={timeOutMessageAudio}
        setTimeOutMessageAudio={setTimeOutMessageAudio}
        welcomeMessageTextOrAudioOptions={welcomeMessageTextOrAudioOptions}
        selectSingleWelcomeTextOrAudio={selectSingleWelcomeTextOrAudio}
        handleSelectSingleWelcomeMessageTextOrAudio={
          handleSelectSingleWelcomeMessageTextOrAudio
        }
        invalidMessageTextOrAudioOptions={invalidMessageTextOrAudioOptions}
        selectSingleInvalidTextOrAudio={selectSingleInvalidTextOrAudio}
        handleSelectSingleInvalidMessageTextOrAudio={
          handleSelectSingleInvalidMessageTextOrAudio
        }
        selectSingleTimeOutTextOrAudio={selectSingleTimeOutTextOrAudio}
        timeOutMessageTextOrAudioOptions={timeOutMessageTextOrAudioOptions}
        handleSelectSingleTimeOutMessageTextOrAudio={
          handleSelectSingleTimeOutMessageTextOrAudio
        }
        gatewayOptions={gatewayOptions}
        handleSelectSingleGateway={handleSelectSingleGateway}
        selectedSingleGateway={selectedSingleGateway}
      />

      <CampaignRemoveModal
        modal_delete={modal_delete}
        setmodal_delete={setmodal_delete}
        tog_delete={tog_delete}
        handleDeleteCampaign={() => {
          dispatch(removeCampaign(listCampaignId));
          setmodal_delete(false);
        }}
      />
    </React.Fragment>
  );
};

export default Campaigns;

AddCampaignModal.js

import {
  Alert,
  Input,
  Label,
  Form,
  FormFeedback,
  Modal,
  ModalBody,
  ModalHeader,
  Row,
  Col,
} from "reactstrap";
import "react-toastify/dist/ReactToastify.css";
import Select from "react-select";

function AddCampaignModal({
  modal_list,
  tog_list,
  formHandleSubmit,
  validation,
  isEditingCampaign,
  alreadyRegisteredError,
  welcomeMessageAudio,
  setWelcomeMessageAudio,
  invalidMessageAudio,
  setInvalidMessageAudio,
  timeOutMessageAudio,
  setTimeOutMessageAudio,
  welcomeMessageTextOrAudioOptions,
  selectSingleWelcomeTextOrAudio,
  handleSelectSingleWelcomeMessageTextOrAudio,
  invalidMessageTextOrAudioOptions,
  selectSingleInvalidTextOrAudio,
  handleSelectSingleInvalidMessageTextOrAudio,
  selectSingleTimeOutTextOrAudio,
  timeOutMessageTextOrAudioOptions,
  handleSelectSingleTimeOutMessageTextOrAudio,
  selectedSingleGateway,
  handleSelectSingleGateway,
  gatewayOptions,
}) {
  return (
    <Modal
      isOpen={modal_list}
      toggle={() => {
        tog_list();
      }}
      centered
      className="modal-lg"
    >
      <ModalHeader
        className="bg-light p-3"
        toggle={() => {
          tog_list();
        }}
      >
        {isEditingCampaign ? "Update Campaign" : "Add Campaign"}
      </ModalHeader>
      <Form className="tablelist-form" onSubmit={(e) => formHandleSubmit(e)}>
        <ModalBody style={{ paddingTop: "0px" }}>
          {alreadyRegisteredError && (
            <Alert color="danger" style={{ marginBlock: "10px" }}>
              {alreadyRegisteredError}
            </Alert>
          )}

          <Row>
            <Col md={6}>
              <div className="mb-2">
                <Label htmlFor="campaignName" className="form-label">
                  Campaign Name
                </Label>

                <Input
                  id="campaignName"
                  name="campaignName"
                  className="form-control"
                  placeholder="Enter Campaign Name"
                  type="text"
                  onChange={validation.handleChange}
                  onBlur={validation.handleBlur}
                  value={validation.values.campaignName || ""}
                  invalid={
                    validation.touched.campaignName &&
                    validation.errors.campaignName
                      ? true
                      : false
                  }
                />

                {validation.touched.campaignName &&
                validation.errors.campaignName ? (
                  <FormFeedback type="invalid">
                    {validation.errors.campaignName}
                  </FormFeedback>
                ) : null}
              </div>
            </Col>

            <Col md={6}>
              <div className="mb-2">
                <Label htmlFor="gatewayId" className="form-label">
                  Gateways
                </Label>

                <Select
                  id="gatewayId"
                  name="gatewayId"
                  value={selectedSingleGateway}
                  onChange={(gateway) => {
                    handleSelectSingleGateway(gateway);
                    validation.setFieldValue("gatewayId", gateway.id);
                  }}
                  gateway
                  options={gatewayOptions}
                  placeholder="Select Gateway"
                  styles={{
                    control: (provided, state) => ({
                      ...provided,
                      borderColor: state.isFocused ? "#a8d9f3" : "#ced4da",
                      "&:hover": {
                        borderColor: "#ced4da",
                      },
                    }),
                  }}
                />
              </div>
            </Col>

            <Col md={6}>
              <div className="mb-2">
                <Label
                  htmlFor="welcomeMessageTextOrAudioSelect"
                  className="form-label"
                >
                  Welcome Message Type
                </Label>

                <Select
                  id="welcomeMessageTextOrAudioSelect"
                  name="welcomeMessageTextOrAudioSelect"
                  value={selectSingleWelcomeTextOrAudio}
                  onChange={(messageOrAudio) => {
                    handleSelectSingleWelcomeMessageTextOrAudio(messageOrAudio);
                  }}
                  options={welcomeMessageTextOrAudioOptions}
                  placeholder="Select Welcome Message Type"
                  styles={{
                    control: (provided, state) => ({
                      ...provided,
                      borderColor: state.isFocused ? "#a8d9f3" : "#ced4da",
                      "&:hover": {
                        borderColor: "#ced4da",
                      },
                    }),
                  }}
                />
              </div>
            </Col>

            {selectSingleWelcomeTextOrAudio?.value === "Text" ? (
              <Col md={6}>
                <div className="mb-2">
                  <Label htmlFor="welcomeMessageText" className="form-label">
                    Welcome Message Text
                  </Label>

                  <Input
                    id="welcomeMessageText"
                    name="welcomeMessageText"
                    className="form-control"
                    placeholder="Enter Welcome Text"
                    type="text"
                    onChange={validation.handleChange}
                    onBlur={validation.handleBlur}
                    value={validation.values.welcomeMessageText}
                    invalid={
                      validation.touched.welcomeMessageText &&
                      validation.errors.welcomeMessageText
                        ? true
                        : false
                    }
                  />

                  {validation.touched.welcomeMessageText &&
                  validation.errors.welcomeMessageText ? (
                    <FormFeedback type="invalid">
                      {validation.errors.welcomeMessageText}
                    </FormFeedback>
                  ) : null}
                </div>
              </Col>
            ) : selectSingleWelcomeTextOrAudio?.value === "Audio" ? (
              <Col lg={6}>
                <div>
                  <Label htmlFor="formFile" className="form-label">
                    Welcome Message Audio
                  </Label>
                  <Input
                    id="welcomeMessageAudio"
                    name="welcomeMessageAudio"
                    className="form-control"
                    type="file"
                    onChange={(e) => setWelcomeMessageAudio(e.target.files[0])}
                  />
                </div>
              </Col>
            ) : (
              <Col lg={6}></Col>
            )}

            <Col md={6}>
              <div className="mb-2">
                <Label htmlFor="invalidMessageText" className="form-label">
                  Invalid Message Type
                </Label>

                <Select
                  id="invalidMessageTextOrAudioSelect"
                  name="invalidMessageTextOrAudioSelect"
                  value={selectSingleInvalidTextOrAudio}
                  onChange={(messageOrAudio) => {
                    handleSelectSingleInvalidMessageTextOrAudio(messageOrAudio);
                  }}
                  options={invalidMessageTextOrAudioOptions}
                  placeholder="Select Welcome Message Type"
                  styles={{
                    control: (provided, state) => ({
                      ...provided,
                      borderColor: state.isFocused ? "#a8d9f3" : "#ced4da",
                      "&:hover": {
                        borderColor: "#ced4da",
                      },
                    }),
                  }}
                />
              </div>
            </Col>

            {selectSingleInvalidTextOrAudio?.value === "Text" ? (
              <Col md={6}>
                <div className="mb-2">
                  <Label htmlFor="welcomeMessageText" className="form-label">
                    Invalid Message Text
                  </Label>

                  <Input
                    id="invalidMessageText"
                    name="invalidMessageText"
                    className="form-control"
                    placeholder="Enter Invalid Text"
                    type="text"
                    onChange={validation.handleChange}
                    onBlur={validation.handleBlur}
                    value={validation.values.invalidMessageText || ""}
                    invalid={
                      validation.touched.invalidMessageText &&
                      validation.errors.invalidMessageText
                        ? true
                        : false
                    }
                  />

                  {validation.touched.invalidMessageText &&
                  validation.errors.invalidMessageText ? (
                    <FormFeedback type="invalid">
                      {validation.errors.invalidMessageText}
                    </FormFeedback>
                  ) : null}
                </div>
              </Col>
            ) : selectSingleInvalidTextOrAudio?.value === "Audio" ? (
              <Col lg={6}>
                <div>
                  <Label htmlFor="formFile" className="form-label">
                    Invalid Message Audio
                  </Label>
                  <Input
                    id="invalidMessageAudio"
                    name="invalidMessageAudio"
                    className="form-control"
                    type="file"
                    onChange={(e) => setInvalidMessageAudio(e.target.files[0])}
                  />
                </div>
              </Col>
            ) : (
              <Col lg={6}></Col>
            )}

            <Col md={6}>
              <div className="mb-2">
                <Label
                  htmlFor="timeOutMessageTextOrAudioSelect"
                  className="form-label"
                >
                  TimeOut Message Type
                </Label>

                <Select
                  id="timeOutMessageTextOrAudioSelect"
                  name="timeOutMessageTextOrAudioSelect"
                  value={selectSingleTimeOutTextOrAudio}
                  onChange={(messageOrAudio) => {
                    handleSelectSingleTimeOutMessageTextOrAudio(messageOrAudio);
                  }}
                  options={timeOutMessageTextOrAudioOptions}
                  placeholder="Select Time Out Message Type"
                  styles={{
                    control: (provided, state) => ({
                      ...provided,
                      borderColor: state.isFocused ? "#a8d9f3" : "#ced4da",
                      "&:hover": {
                        borderColor: "#ced4da",
                      },
                    }),
                  }}
                />
              </div>
            </Col>

            {selectSingleTimeOutTextOrAudio?.value === "Text" ? (
              <Col md={6}>
                <div className="mb-2">
                  <Label htmlFor="timeOutMessageText" className="form-label">
                    TimeOut Message Text
                  </Label>

                  <Input
                    id="timeOutMessageText"
                    name="timeOutMessageText"
                    className="form-control"
                    placeholder="Enter TimeOut Text"
                    type="text"
                    onChange={validation.handleChange}
                    onBlur={validation.handleBlur}
                    value={validation.values.timeOutMessageText || ""}
                    invalid={
                      validation.touched.timeOutMessageText &&
                      validation.errors.timeOutMessageText
                        ? true
                        : false
                    }
                  />
                </div>
              </Col>
            ) : selectSingleTimeOutTextOrAudio?.value === "Audio" ? (
              <Col lg={6}>
                <div>
                  <Label htmlFor="formFile" className="form-label">
                    TimeOut Message Audio
                  </Label>
                  <Input
                    id="timeOutMessageAudio"
                    name="timeOutMessageAudio"
                    className="form-control"
                    type="file"
                    onChange={(e) => setTimeOutMessageAudio(e.target.files[0])}
                  />
                </div>
              </Col>
            ) : (
              <Col lg={6}></Col>
            )}
          </Row>

          <div className="text-end">
            <button type="submit" className="btn btn-primary">
              {isEditingCampaign ? "Update Campaign" : "Save Campaign"}
            </button>
          </div>
        </ModalBody>
      </Form>
    </Modal>
  );
}

export default AddCampaignModal;