I am trying to do a file upload but the whole component refreshes every time. I have 3 steps here, 1st one takes name, 2nd takes address and the third one takes profile pic. In third step when the user clicks on the button to select file from file system the whole stepper components gets reloaded.
Is there a different way I can use file upload? I am not sure if I can put things together with the formik values.
export default function Test() {
const showFileToUpload = (e) => {
console.log("files", e);
//then perform some requests to save these images
};
return (
<FormikStepper
initialValues={{
firstName: "",
address: "",
file: ""
}}
onSubmit={async (values) => {
console.log("values", values);
}}
>
<FormikStep label="Basic Details">
<FormControl>
<Field
type="text"
name="firstName"
label="Name"
component={TextField}
autoComplete="off"
/>
</FormControl>
</FormikStep>
<FormikStep label="Other details">
<FormControl>
<Field
type="text"
name="address"
label="address"
component={TextField}
autoComplete="off"
/>
</FormControl>
</FormikStep>
<FormikStep
label="Upload Files"
showFileToUpload={(w) => {
console.log(w);
}}
>
<div className="form-group">
<label>Upload your images</label>
<input
id="file"
name="file"
type="file"
multiple={true}
onChange={(e) => {
showFileToUpload(e.currentTarget.files);
}}
/>
{/* <Thumb file={values.file} /> */}
</div>
</FormikStep>
</FormikStepper>
);
}
export function FormikStep({ children, ...props }) {
console.log("valuessss", props);
return (
<Card style={{ width: "100%", marginBottom: "20px", padding: "10px" }}>
<CardContent
className="cardContentCustom"
style={{
width: "100%",
marginBottom: "20px",
display: "flex",
flexWrap: "wrap"
}}
>
{children}
</CardContent>
</Card>
);
}
export function FormikStepper({ children, ...props }) {
const childrenArray = React.Children.toArray(children);
const [step, setStep] = useState(0);
const currentChild = childrenArray[step];
const [completed, setCompleted] = useState(false);
console.log("values", props, childrenArray);
function isLastStep() {
return step === childrenArray.length - 1;
}
return (
<Formik
{...props}
validationSchema={currentChild.props.validationSchema}
onSubmit={async (values, helpers) => {
console.log("--------", props);
if (isLastStep()) {
await props.onSubmit(values, helpers);
setCompleted(true);
} else {
setStep((s) => s + 1);
}
}}
>
{({ isSubmitting }) => (
<Form autoComplete="off">
<Card
style={{
width: "100%",
marginBottom: "20px",
height: "fit-content"
}}
>
<CardContent style={{ width: "100%" }}>
<Stepper alternativeLabel activeStep={step}>
{childrenArray.map((child, index) => (
<Step
key={child.props.label}
completed={step > index || completed}
>
<StepLabel>{child.props.label}</StepLabel>
</Step>
))}
</Stepper>
</CardContent>
</Card>
{currentChild}
<Grid container spacing={2}>
{step > 0 ? (
<Grid item>
<Button
disabled={isSubmitting}
variant="contained"
color="primary"
onClick={() => setStep((s) => s - 1)}
>
Back
</Button>
</Grid>
) : null}
<Grid item>
<Button
startIcon={
isSubmitting ? <CircularProgress size="1rem" /> : null
}
disabled={isSubmitting}
variant="contained"
color="primary"
type="submit"
>
{isSubmitting ? "Submitting" : isLastStep() ? "Submit" : "Next"}
</Button>
</Grid>
</Grid>
</Form>
)}
</Formik>
);
}
Here is the link for codesandbox: https://codesandbox.io/s/suspicious-hooks-g0wpl?file=/src/Test.js