how to use material-ui select field with formik?
Asked Answered
H

1

6

I'm tryin to use formik with material-ui Textfield componet with select attr, everytime i change option it gives me this Warning

Material-UI: You have provided an out-of-range value null for the select (name="subIndicatorId") component. Consider providing a value that matches one of the available options or ''. The available values are 1, 2, 3, 4, 5, 55, 161, 162, 163, 164, 193, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 262, 263, 264, 265, 266, 267, 268, 271, 286, 288, 289, 295, 300, 303, 304, 306, 307, 311, 341

alsol i get this Warning when the page render first time

Warning: value prop on input should not be null. Consider using an empty string to clear the component or undefined for uncontrolled components.

here is the code for this

import React, { useState, useEffect } from "react";

import Button from "@material-ui/core/Button";
import TextField from "@material-ui/core/TextField";

import { Col, Container, Row } from "react-bootstrap";

import { useFormik } from "formik";
import * as yup from "yup";

import { axios } from "../Axios/Axios";

import icommodityGroup from "../../assets/images/png/product.png";
import wheatBag from "../../assets/images/png/Wheat Bag.png";
import flag from "../../assets/images/png/flag.png";
import { MenuItem } from "@material-ui/core";

const RetailPrices = () => {
  const [genralIndicators, setGenralIndicators] = useState([]);
  const [governorates, setGovernorate] = useState([]);
  const [subIndicator, setSubIndicator] = useState([]);
  const [classification, setClassification] = useState();

  const getPopulate = async () => {
    const response = await axios
      .get("/home/PopulateDropDowns")
      .catch((err) => console.log("Error", err)); //handle errors
    if (response && response.data) {
      console.log(response);
      setGenralIndicators(response.data.genralIndicators);
      setGovernorate(response.data.governorates);
      setClassification(response.data.classification);
    }
  };

  const getSubindicator = async (id) => {
    console.log(id);
    const response = await axios
      .get(`/home/SubIndicator/${id}`)
      .catch((err) => console.log("Error", err)); //handle errors
    if (response && response.data) {
      setSubIndicator(response.data);
    }
  };

  useEffect(() => {
    getPopulate();
  }, []);

  const handleGenralIndicatorsChange = (e) => {
    getSubindicator(e.target.value);
  };

  // Schema for yup
  const validationSchema = yup.object({
    commodityGroup: yup
      .string("أختر المجموعة السلعية")
      .required("أختر المجموعة السلعية "),
    // commodity: yup.string("أختر السلعة").required("أختر السلعة"),
    // city: yup.string("أختر المدينة").required("أختر المدينة"),
  });

  const formik = useFormik({
    initialValues: {
      ClassificationId: 1,
      GeneralIndicatorId: null,
      GovernorateId: null,
      subIndicatorId: null,
    },
    // validationSchema: validationSchema,

    onSubmit: async (values) => {
      alert(JSON.stringify(values, null, 2));
      const response = await axios
        .post("/home/PriceSearch", JSON.stringify(values, null, 2))
        .catch((err) => console.log("Error", err)); //handle errors;
      if (response) {
        alert("sucess!");
        console.log(response);
      }
    },
  });

  return (
    <div>
      <form onSubmit={formik.handleSubmit}>
        <Row>
          <Col className="px-0">
            <img
              className="p-1"
              src={icommodityGroup}
              alt="icon_1"
              style={{
                borderRadius: "6px",
                boxShadow: "10px 10px 5px 0px rgba(179, 179, 179, 0.36)",
              }}
            />

            <TextField
              style={{ width: "200px" }}
              className="px-2 my-2"
              variant="outlined"
              name="GeneralIndicatorId"
              id="المجموعة السلعية"
              select
              label="المجموعة السلعية"
              value={formik.values.GeneralIndicatorId}
              onChange={(e) => {
                formik.handleChange(e);
                handleGenralIndicatorsChange(e);
              }}
              error={
                formik.touched.genralIndicators &&
                Boolean(formik.errors.genralIndicators)
              }
              helperText={
                formik.touched.genralIndicators &&
                formik.errors.genralIndicators
              }
            >
              {genralIndicators.map((option) => (
                <MenuItem key={option.id} value={option.id}>
                  {option.name}
                </MenuItem>
              ))}
            </TextField>
          </Col>
          <Col className="px-0">
            <img
              className="p-1"
              src={wheatBag}
              alt="icon_1"
              style={{
                borderRadius: "6px",
                boxShadow: "10px 10px 5px 0px rgba(179, 179, 179, 0.36)",
              }}
            />
            <TextField
              style={{ width: "200px" }}
              className="px-2 my-2"
              variant="outlined"
              name="subIndicatorId"
              id="السلعة"
              select
              label="السلعة"
              value={formik.values.subIndicatorId}
              onChange={formik.handleChange}
              error={
                formik.touched.subIndicator &&
                Boolean(formik.errors.subIndicator)
              }
              helperText={
                formik.touched.subIndicator && formik.errors.subIndicator
              }
            >
              {subIndicator.map((option) => (
                <MenuItem key={option.id} value={option.id}>
                  {option.name}
                </MenuItem>
              ))}
            </TextField>
          </Col>
          <Col className="px-0">
            <img
              className="p-1"
              src={flag}
              alt="icon_1"
              style={{
                borderRadius: "6px",
                boxShadow: "10px 10px 5px 0px rgba(179, 179, 179, 0.36)",
              }}
            />
            <TextField
              style={{ width: "200px" }}
              className="px-2 my-2"
              variant="outlined"
              name="GovernorateId"
              id="المحافظة"
              select
              label="المحافظة"
              value={formik.values.GovernorateId}
              onChange={formik.handleChange}
              error={
                formik.touched.governorates &&
                Boolean(formik.errors.governorates)
              }
              helperText={
                formik.touched.governorates && formik.errors.governorates
              }
            >
              {governorates.map((option) => (
                <MenuItem key={option.id} value={option.id}>
                  {option.name}
                </MenuItem>
              ))}
            </TextField>
          </Col>
          <Col>
            <Button
              className="p-3 my-2 "
              size="large"
              variant="contained"
              type="submit"
              style={{
                color: "#fff",
                backgroundColor: "var(--main-green)",
                width: "200px",
              }}
            >
              إرسال
            </Button>
          </Col>
        </Row>
      </form>
    </div>
  );
};

export default RetailPrices;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

it works fine and return response, but i want to handle these two warnings

Harakiri answered 4/2, 2021 at 14:9 Comment(0)
C
6

Warning: value prop on input should not be null. Consider using an empty string to clear the component or undefined for uncontrolled components. Since oyu are suing controlled components, all values need to be defiend in render:

GeneralIndicatorId: null,
      GovernorateId: null,
      subIndicatorId: null,

But those are undefined/null, so setting those to "" would fix this.

Material-UI: You have provided an out-of-range value null for the select (name="subIndicatorId") component. Consider providing a value that matches one of the available options or ''.

For selects all values that are possible need to be an option, but since those are null and you have no null option, it throws this error. Just add a new empty option:

 <TextField
              style={{ width: "200px" }}
              className="px-2 my-2"
              variant="outlined"
              name="GovernorateId"
              id="المحافظة"
              select
              label="المحافظة"
              value={formik.values.GovernorateId}
              onChange={formik.handleChange}
              error={
                formik.touched.governorates &&
                Boolean(formik.errors.governorates)
              }
              helperText={
                formik.touched.governorates && formik.errors.governorates
              }
            >
               <MenuItem key={""} value={""}>
                  No Selected // Or Empty
                </MenuItem>
              {governorates.map((option) => (
                <MenuItem key={option.id} value={option.id}>
                  {option.name}
                </MenuItem>
              ))}
            </TextField>
Chalco answered 4/2, 2021 at 14:15 Comment(1)
it works, i added a new empty option but set its value null <MenuItem value={null}>No Selected</MenuItem> just because i want to post null value to the server if the user didn't select any choice. thank you so muchHarakiri

© 2022 - 2024 — McMap. All rights reserved.