如何在Formik中使用Material-UI的选择字段?

6

我正在尝试将 formik 和 material-ui 的 Textfield 组件一起使用,其中包含 select 属性。每当我更改选项时,它都会给出此警告:

Material-UI:您为选择器(name="subIndicatorId")组件提供了一个超出范围的值 null。 请考虑提供与可用选项之一相匹配的值或 ''。 可用值为 1234555161162163164193233234235236237238239240241242243244245246262263264265266267268271286288289295300303304306307311341

当页面首次渲染时,我也会收到此警告:

警告:在 input 上的 value 属性不应为 null。考虑使用空字符串来清除组件或对于不受控制的组件使用 undefined

这是代码:

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>

这段代码能够正常运行并返回响应,但是我想处理这两个警告

1个回答

6
警告:输入框上的值 prop 不应该为 null。考虑使用空字符串来清空组件,或者对于未受控组件使用 undefined。 由于你正在使用受控组件,请在渲染时定义所有的值:
GeneralIndicatorId: null,
      GovernorateId: null,
      subIndicatorId: null,

但这些值是未定义/空的,因此将其设置为""即可解决此问题。

Material-UI:您已提供一个超出范围的值null给选择器(name="subIndicatorId")组件,请考虑提供与可用选项之一匹配的值或 ''。

对于选择器而言,所有可能的值都需要成为一个选项,但由于这些值是null且没有null选项,因此会引发此错误。只需添加一个新的空选项:

 <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>

它可以工作了,我添加了一个新的空选项,但将其值设置为null: <MenuItem value={null}>未选择</MenuItem> 只是因为我想在用户未选择任何选项时向服务器提交null值。 非常感谢。 - mostafa elbanna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接