react-number-format doesn't work with Formik and Mui

471 Views Asked by At

I tried to use react-number-format with mui TextField and Formik, when I submit the form I get a required error. Its seems that nested TextFiled with react-number-format can't get the values.

I tried to console log the input but whit react-number-format I get empty string.

//App.jsx

import * as React from "react";

import { Typography, InputAdornment, Grid } from "@mui/material";

import { Formik, Form } from "formik";

import * as Yup from "yup";
import { NumericFormat } from "react-number-format";

import axios from "axios";
import { FieldWrapper as TextField } from "./InputTem";
import { BtnTemp as Button } from "./Btn";

import "./styles.css";

const FORM_STATE = {
  price: ""
};

const priceProps = {
  name: "price",
  label: "Price",
  InputProps: {
    startAdornment: <InputAdornment position="start">€</InputAdornment>
  },
  required: true
};

const FORM_VALIDATION = Yup.object().shape({
  price: Yup.number().required("require")
});

const App = () => {
  return (
    <Grid container flex justifyContent={"center"}>
      <Formik
        initialValues={{ ...FORM_STATE }}
        validationSchema={FORM_VALIDATION}
        onSubmit={(values) => {
          console.log(values);
        }}
      >
        <Form>
          <Grid
            container
            spacing={2}
            rowGap={1}
            padding={3}
            maxWidth={1000}
            justifyContent={"center"}
          >
            <Grid item xs={12}>
              <Typography
                variant="h3"
                component="h1"
                align="center"
                color="#280982"
              >
                Price Validation Error
              </Typography>
            </Grid>
            <Grid item xs={12}>
              <Grid item xs={12}>
                <NumericFormat
                  name="price"
                  id="price"
                  thousandSeparator=","
                  allowNegative={false}
                  decimalScale={2}
                  decimalSeparator="."
                  fixedDecimalScale={true}
                  customInput={TextField}
                  {...priceProps}
                />
              </Grid>
              <Grid container marginTop="1rem">
                <Button>submit</Button>
              </Grid>
            </Grid>
          </Grid>
        </Form>
      </Formik>
    </Grid>
  );
};

export default App;

// Input.jsx 

import * as React from "react";
import TextField from "@mui/material/TextField";
import { useField } from "formik";

export const FieldWrapper = ({ name, ...otherProps }) => {
  const [field, meta] = useField(name);
  if (meta && meta.touched && meta.error) {
    otherProps.error = true;
    otherProps.helperText = meta.error;
  }

  const configText = {
    ...field,
    ...otherProps,
    fullWidth: true,
    variant: "outlined"
  };

  return <TextField {...configText} />;
};

export default FieldWrapper;

//BtnTemplate.jsx

 import { Button } from "@mui/material";
import { useFormikContext } from "formik";

export const BtnTemp = ({ children, ...otherProps }) => {
  const { submitForm } = useFormikContext();
  const formHandler = () => {
    submitForm();
  };

  const btnConfig = {
    ...otherProps,
    fullWidth: true,
    variant: "outlined",
    onClick: formHandler
  };
  return <Button {...btnConfig}>{children}</Button>;
};

andhere is a link for CodeSandbox

Thanks in advancce !

1

There are 1 best solutions below

0
Luft On

Now its works ! just passed the usedField props.

here is the solution in sandbox

import * as React from "react";
import { NumericFormat } from "react-number-format";

import { useField } from "formik";

const PriceTemp = ({ name, ...otherProps }) => {
  const [field, meta] = useField(name);

  const passwordConfig = {
    ...field,
    ...otherProps,
    name: "price",
    label: "Price",
    thousandSeparator: ",",
    allowNegative: false,
    decimalScale: 2,
    decimalSeparator: ".",
    fixedDecimalScale: true
  };

  return <NumericFormat {...passwordConfig} />;
};

export default PriceTemp

;