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

Time:02-05

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 !

CodePudding user response:

It looks like the issue you are experiencing is due to the fact that Formik is not able to access the value of the NumericFormat component. You can try passing the value from the NumericFormat component to the TextField component as a prop, and then passing it to Formik. Alternatively, you can try using the useField hook and passing the value to Formik directly.

CodePudding user response:

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

;

  • Related