我一直有这个错误:一个组件正在将文本类型的受控输入更改为不受控制。输入元素不应从受控切换到不受控(反之亦然)。决定在组件的生命周期内使用受控输入元素还是不受控输入元素。当我尝试单击编辑将数据库中的值放入输入框中时
这是我的反应代码:
const initialValues = {
medTestId: '',
healthcareProviderId: '',
accountId: '',
newbornId: '',
paymentStatus: '',
completionStatus: false,
dateCompleted: ''
};
const validationSchema = Yup.object().shape({
medTestId: Yup.string()
.required('Test is required'),
healthcareProviderId: Yup.string()
.required('Healthcare Provider is required'),
accountId: Yup.string()
.required('Patient is required'),
newbornId: Yup.string()
.required('Newborn is required'),
paymentStatus: Yup.string()
.required('Payment Status is required'),
completionStatus: Yup.bool()
.oneOf([true], 'Completion Status is required'),
dateCompleted: Yup.date()
});
const DatePickerField = ({...props}) => {
const {setFieldValue} = useFormikContext();
const [field] = useField(props);
return(
<DatePicker
{...field}
{...props}
selected={(field.value && new Date(field.value)) || null}
onChange={val => {
setFieldValue(field.name, val);
}}
/>
);
};
function onSubmit(fields, { setStatus, setSubmitting }) {
setStatus();
if (isAddMode) {
createmedTestOrder(fields, setSubmitting);
} else {
updatemedTestOrder(id, fields, setSubmitting);
}
}
function createmedTestOrder(fields, setSubmitting) {
medTestOrderService.create(fields)
.then(() => {
alertService.success('Test Order added successfully', { keepAfterRouteChange: true });
history.push('.');
})
.catch(error => {
setSubmitting(false);
alertService.error(error);
});
}
function updatemedTestOrder(id, fields, setSubmitting) {
medTestOrderService.update(id, fields)
.then(() => {
alertService.success('Update successful', { keepAfterRouteChange: true });
history.push('..');
})
.catch(error => {
setSubmitting(false);
alertService.error(error);
});
}
return (<div className="Col-md-10 offset-md-1" style={{
marginTop: '20px'
}}>
<Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={onSubmit}>
{({ errors, touched, isSubmitting, values, setFieldValue }) => {
useEffect(() => {
if (!isAddMode) {
// get user and set form fields
medTestOrderService.getById(id).then(user => {
const fields = ['medTestId', 'healthcareProviderId', 'accountId', 'newbornId', 'paymentStatus', 'dateCompleted','completionStatus'];
fields.forEach(field => setFieldValue(field, user[field], false));
});
}
}, []);
return (
<Form>
<h1>{isAddMode ? 'Add Test Order' : 'Edit Test Order'}</h1>
<div className="form-row">
<div className="form-group col-4">
<label>Test</label>
<Field name="medTestId" as="select" className={'form-control' + (errors.medTestId && touched.medTestId ? ' is-invalid' : '')}>
<option value=""></option>
{medtests && medtests.map( medtest =>
<option key={medtest.id} value={medtest.id}>{medtest.name}</option>
)}
</Field>
<ErrorMessage name="medTestId" component="div" className="invalid-feedback" />
</div>
<div className="form-group col-4">
<label>Healthcare Provider</label>
<Field name="healthcareProviderId" as="select" className={'form-control' + (errors.healthcareProviderId && touched.healthcareProviderId ? ' is-invalid' : '')}>
<option value=""></option>
{healthcareproviders && healthcareproviders.map( healthcareprovider =>
<option key={healthcareprovider.id} value={healthcareprovider.id}>{healthcareprovider.fullName}</option>
)}
</Field>
<ErrorMessage name="healthcareProviderId" component="div" className="invalid-feedback" />
</div>
<div className="form-group col-4">
<label>Patient</label>
<Field name="accountId" as="select" className={'form-control' + (errors.accountId && touched.accountId ? ' is-invalid' : '')}>
<option value=""></option>
{accounts && accounts.map( account =>
<option key={account.id} value={account.id} >{account.firstName} {account.lastName}</option>
)}
</Field>
<ErrorMessage name="accountId" component="div" className="invalid-feedback" />
</div>
</div>
<div className="form-row">
<div className="form-group col-3">
<label>Newborn</label>
<Field name="newbornId" as="select" className={'form-control' + (errors.newbornId && touched.newbornId ? ' is-invalid' : '')}>
<option value=""></option>
{newborns && newborns.map( newborn =>
<option key={newborn.id} value={newborn.id}>{newborn.firstName} {newborn.lastName}</option>
)}
</Field>
<ErrorMessage name="newbornId" component="div" className="invalid-feedback" />
</div>
<div className="form-group col-3">
<label>Payment Status</label>
<Field name="paymentStatus" as="select" className={'form-control' + (errors.paymentStatus && touched.paymentStatus ? ' is-invalid' : '')}>
<option value=""></option>
<option value="Complete Payment">Complete Payment</option>
<option value="Incomplete Payment">Incomplete Payment</option>
<option value="Unpaid">Unpaid</option>
</Field>
<ErrorMessage name="paymentStatus" component="div" className="invalid-feedback" />
</div>
<div className="form-group col-3">
<label>Date Completed</label>
<DatePickerField name="dateCompleted" value={values.dateCompleted} onChange={setFieldValue} className={'form-control' + (errors.dateCompleted && touched.dateCompleted ? ' is-invalid' : '')}>
</DatePickerField>
<ErrorMessage name="dateCompleted" component="div" className="invalid-feedback" />
</div>
<div className="form-group form-check" style={{marginTop: '35px', marginLeft: '20px'}}>
<Field type="checkbox" name="completionStatus" className={'form-check-input ' + (errors.CompletionStatus && touched.CompletionStatus ? ' is-invalid' : '')} />
<label htmlFor="completionStatus" className="form-check-label">Order Completed ?</label>
<ErrorMessage name="completionStatus" component="div" className="invalid-feedback" />
</div>
</div>
<div className="form-group">
<button type="submit" disabled={isSubmitting} className="btn btn-primary">
{isSubmitting && <span className="spinner-border spinner-border-sm mr-1"></span>}
Save
</button>
<Link to={isAddMode ? '.' : '..'} className="btn btn-link">Cancel</Link>
</div>
</Form>
);
}}
</Formik>
</div>
);