Joseph Morgan
3 Jul 2021
React js
How can i use SetFieldValue() from outside the main function (render function)? I am trying to set the value of the input from another function and this input is required in the validation so I cannot leave it empty and set the value on form submit?
So I need to setFieldValue from the function called getPriceUsingID because this function gets the price from the backend, How can I set the value of the price field?
import React from 'react';
import * as Yup from 'yup';
import { Formik } from 'formik';
import {
Button,
Grid,
TextField,
} from '@material-ui/core';
import axios from 'axios';
const PriceCalculator = ({
className,
...rest
}) => {
const getPriceUsingID = async (id) => {
let res = await axios.get('//localhost/prices/'+id);
let price = res.data.price;
console.log(price);
}
return (
<Formik
enableReinitialize={true}
initialValues={{
productID: '',
price: '',
}}
validationSchema={Yup.object().shape({
productID: Yup.string().max(255).required('Amount is required'),
price: Yup.string().max(255).required('Price is required'),
})}
onSubmit={async (values, {
setErrors,
setStatus,
setSubmitting,
}) => {
try {
console.log(values);
} catch (err) {
console.error(err);
setStatus({ success: false });
setErrors({ submit: err.message });
setSubmitting(false);
}
}}
>
{({
errors,
handleBlur,
handleChange,
handleSubmit,
isSubmitting,
touched,
values,
setFieldValue
}) => (
<form
onSubmit={handleSubmit}
{...rest}
>
<Grid container>
<Grid container spacing={3}>
<Grid item xs={12}>
<TextField
error={Boolean(touched.productID && errors.productID)}
fullWidth
helperText={touched.productID && errors.productID}
label="Amount"
name="productID"
onBlur={handleBlur}
value={values.productID}
onChange={(e) => { handleChange(e); getPriceUsingID(e.target.value); }}
variant="outlined"
/>
</Grid>
<Grid item xs={12}>
<TextField
error={Boolean(touched.price && errors.price)}
fullWidth
helperText={touched.price && errors.price}
label="Price"
name="price"
value={values.price}
onBlur={handleBlur}
onChange={handleChange}
variant="outlined"
/>
</Grid>
<Button
color="secondary"
disabled type="submit"
variant="contained"
size="large"
>
Submit
</Button>
</Grid>
</Grid>
</form>
)}
</Formik>
);
};
export default PriceCalculator;
Hey Joseph, there are two ways to achieve this,
The first way is by using setFieldValue inside the form and pass the Product ID to the outside function and return the price exactly like what you did in the code above
const getPriceUsingID = async (id) => {
let res = await axios.get('//localhost/prices/'+id);
let price = res.data.price;
console.log(price);
return price;
}
and the onChange function gonna look like this
<TextField
error={Boolean(touched.productID && errors.productID)}
fullWidth
helperText={touched.productID && errors.productID}
label="Amount"
name="productID"
onBlur={handleBlur}
value={values.productID}
onChange={(e) => { handleChange(e); setFieldValue('price', getPriceUsingID(e.target.value)); }}
variant="outlined"
/>
The second way is by passing the setFieldValue function to the outside function getPriceUsingID Like
const getPriceUsingID = async (id, setFieldValue) => {
let res = await axios.get('//localhost/prices/'+id);
let price = res.data.price;
console.log(price);
setFieldValue('price', price);
}
and the field function gonna look like this
<TextField
error={Boolean(touched.productID && errors.productID)}
fullWidth
helperText={touched.productID && errors.productID}
label="Amount"
name="productID"
onBlur={handleBlur}
value={values.productID}
onChange={(e) => { handleChange(e); getPriceUsingID(e.target.value, setFieldValue); }}
variant="outlined"
/>
Note: you need to keep the price field as it is above, and it's gonna be fine,
Hope you could figure out your issue
Good Luck
Joseph Morgan
3 Jul 2021
Amazing, this is really what I need
© 2024 Copyrights reserved for web-brackets.com