我面临一个问题,即当我提交表单时,无论是否成功,整个表单字段都会重置。所以我假设这是因为组件正在重新渲染。
我想在提交表单时,无论网络请求是否成功,我希望它仍然保持字段内容
下面是整个代码的样子:
import { Formik, FieldArray } from 'formik';
import * as Yup from 'yup';
import React, { useEffect } from 'react';
import * as Style from './create-lesson-form.styles';
import { ReactComponent as AddNewIcon } from '../../assets/add-new.svg';
import { ReactComponent as RemoveRecent } from '../../assets/remove-recent.svg';
import CustomButton from '../custom-button/custom-button.component';
import SimpleCheckBox from '../field-inputs/simple-checkbox/simple-checkbox.component';
import { createALessonNote } from '../../redux/lesson_note/lesson_note.actions';
import { LessonNotePayload } from '../../redux/lesson_note/lesson_note.types';
import { connect } from 'react-redux';
import { CreateLessonPropType } from './create-lesson-form.types';
import ToastAlert from '../toast/toast.components';
import { createStructuredSelector } from 'reselect';
import {
selectLessonCreationIsSuccess,
selectLessonNoteError,
selectLessonNoteSuccess,
} from '../../redux/lesson_note/lesson_note.selector';
import { selectSubjects } from '../../redux/subject/subject.selector';
import { fetchSubjectAction } from '../../redux/subject/subject.action';
import { fetchLevelAction } from '../../redux/level/level.action';
import { selectLevels } from '../../redux/level/level.selectors';
const CreateLessonForm: React.FC<CreateLessonPropType> = ({
createLessonNote,
fetchSubjects,
fetchLevels,
lesson_note_error,
lesson_note_success,
isLessonCreated,
subjects,
levels,
}) => {
const handleAddStepsField = (values: any, setValues: any) => {
const steps = [...values.steps];
steps.push('');
setValues({ ...values, steps });
};
const handleAddParagraphField = (values: any, setValues: any) => {
const paragraphs = [...values.paragraphs];
paragraphs.push('');
setValues({ ...values, paragraphs });
};
const handleDeleteParagraphFields = (values: any, setValues: any) => {
const paragraphs = [...values.paragraphs];
paragraphs.pop();
setValues({ ...values, paragraphs });
};
const handleDeleteStepsFields = (values: any, setValues: any) => {
const steps = [...values.steps];
steps.pop();
setValues({ ...values, steps });
};
const fetchFormValues = async (values: any) => {
const lessonPayload: LessonNotePayload = {
class_id: values.class,
subject_id: values.subject,
topic: values.topic,
is_published: values.is_published,
lesson_body: values.paragraphs,
lesson_plan: values.steps,
};
await createLessonNote(lessonPayload);
};
useEffect(() => {
fetchSubjects();
fetchLevels();
}, []);
return (
<Style.CreateLessonNoteContainer>
{lesson_note_error.length ? <ToastAlert message={lesson_note_error} type="failure" /> : null}
{isLessonCreated ? <ToastAlert message={lesson_note_success} type="success" /> : null}
<Formik
/**
*Declare field initial values
*/
initialValues={{
topic: '',
subject: '',
class: '',
is_published: false,
date_of_delivery: '',
paragraphs: [],
steps: [],
}}
/**
* validate form on client side
*/
validationSchema={Yup.object({
topic: Yup.string().required(),
subject: Yup.string().required(),
class: Yup.number().required(),
date_of_delivery: Yup.date().required(),
paragraphs: Yup.array().of(Yup.string().required()),
steps: Yup.array().of(Yup.string().required()),
})}
/**
* listen to user submit action
*/
onSubmit={async (values, { setSubmitting, resetForm }) => {
alert(values);
console.log(values);
await fetchFormValues(values);
if (isLessonCreated) {
resetForm();
console.log('reset form');
}
setSubmitting(false);
}}
>
{({ values, setValues }) => (
<>
<Style.FormTag>
<Style.LessonBodyFooter>
<Style.LessonHeadInput>
<Style.LessonParagraphHeader>
<h3>Lesson Header</h3>
</Style.LessonParagraphHeader>
<Style.CustomTextInput label="Topic" name="topic" type="text" />
<Style.CustomSelectDropdown label="Subject" name="subject">
<option value={''} disabled selected>
select subject
</option>
{subjects.map((subject) => {
return (
<option key={subject.id} value={subject.id}>
{subject.title}
</option>
);
})}
</Style.CustomSelectDropdown>
<Style.CustomSelectDropdown label="Level" name="class">
<option value={''} disabled selected>
select level
</option>
{levels.map((level) => {
return (
<option key={level.id} value={level.id}>
{level.title}
</option>
);
})}
</Style.CustomSelectDropdown>
<Style.CustomTextInput
label="Date of delivery"
name="date_of_delivery"
type="date"
/>
</Style.LessonHeadInput>
<Style.LessonParagraphContainer>
<Style.LessonParagraphHeader>
<h3>Lesson Paragraphs</h3>
<div>
<RemoveRecent
onClick={() => handleDeleteParagraphFields(values, setValues)}
/>
<AddNewIcon onClick={() => handleAddParagraphField(values, setValues)} />
</div>
</Style.LessonParagraphHeader>
<Style.LessonParagraphFieldContainer>
<FieldArray name={'paragraphs'}>
{() =>
values.paragraphs.map((_, index) => {
return (
<Style.LessonParagraphFieldDiv key={index}>
<Style.CustomTextArea
label={`Paragraph ${index + 1}`}
name={`paragraphs.${index}`}
/>
</Style.LessonParagraphFieldDiv>
);
})
}
</FieldArray>
</Style.LessonParagraphFieldContainer>
</Style.LessonParagraphContainer>
<Style.LessonStepContainer>
<Style.LessonParagraphHeader>
<h3>Lesson Steps</h3>
<div>
<RemoveRecent onClick={() => handleDeleteStepsFields(values, setValues)} />
<AddNewIcon onClick={() => handleAddStepsField(values, setValues)} />
</div>
</Style.LessonParagraphHeader>
<Style.LessonParagraphFieldContainer>
<FieldArray name={'steps'}>
{() =>
values.steps.map((_, index) => {
return (
<Style.LessonParagraphFieldDiv key={index}>
<Style.CustomTextArea
label={`Step ${index + 1}`}
name={`steps.${index}`}
/>
</Style.LessonParagraphFieldDiv>
);
})
}
</FieldArray>
</Style.LessonParagraphFieldContainer>
</Style.LessonStepContainer>
</Style.LessonBodyFooter>
<Style.LessonFormFooter>
<SimpleCheckBox name={'is_published'}>Publish Note</SimpleCheckBox>
<CustomButton type="submit">Submit</CustomButton>
</Style.LessonFormFooter>
</Style.FormTag>
</>
)}
</Formik>
</Style.CreateLessonNoteContainer>
);
};
const mapStateToProps = createStructuredSelector({
lesson_note_error: selectLessonNoteError,
isLessonCreated: selectLessonCreationIsSuccess,
lesson_note_success: selectLessonNoteSuccess,
subjects: selectSubjects,
levels: selectLevels,
});
const mapDispatchToProps = (dispatch: any) => {
return {
createLessonNote: ({
class_id,
subject_id,
topic,
is_published,
lesson_body,
lesson_plan,
}: LessonNotePayload) =>
dispatch(
createALessonNote({
class_id,
subject_id,
topic,
is_published,
lesson_body,
lesson_plan,
}),
),
fetchSubjects: () => dispatch(fetchSubjectAction()),
fetchLevels: () => dispatch(fetchLevelAction()),
};
};
export default connect(mapStateToProps, mapDispatchToProps)(CreateLessonForm);