提交表单后,我将对值进行url编码,然后在API请求中将其发送。但是,当我对这些值进行编码时,它们会显示在已编码的表单中:
为什么要更改formik值?我正在尝试克隆我正在编码的对象,以便不更新formik值,但它们仍会更新。
代码:
export const uploadAddProductEpic: Epic<*, *, *> = (
action$: ActionsObservable<*>
) =>
action$.ofType(UPLOAD_ADD_PRODUCT).mergeMap((action) => {
const newAction = Object.assign({}, encodeAddProductAction(action))
return ajax
.post('http://192.168.1.12:4000/products', newAction.payload, {
'Content-': 'application/json'
})
.map((response) => uploadAddProductFulfilled(response))
.catch((error) => Observable.of(uploadAddProductRejected(error)))
})
export const handleSubmit = (values, props: AddViewProps): void => {
Toast.show('Uploading Product', {
duration: 3000,
position: 30,
shadow: true,
animation: true,
hideOnPress: true,
delay: 0
})
props.uploadAddProduct(values)
}
export const encodeAddProductAction = (action: VepoAction<Product>) => {
const action1 = Object.assign({}, action)
action1.payload.Shop = encodeURIComponent(
JSON.stringify(action1.payload.Shop)
)
action1.payload.Brand = encodeURIComponent(
JSON.stringify(action1.payload.Brand)
)
action1.payload.Name = encodeURIComponent(
JSON.stringify(action1.payload.Name)
)
action1.payload.Description = encodeURIComponent(
JSON.stringify(action1.payload.Description)
)
return action1
}
const mapStateToProps = (state: RecordOf<VepoState>) => ({
locationListDisplayed: state.formControls.root.locationListDisplayed
})
// eslint-disable-next-line flowtype/no-weak-types
const mapDispatchToProps = (dispatch: Dispatch<*>): Object => ({
uploadAddProduct: (product: Product): void => {
dispatch(uploadAddProduct(product))
}
})
class AddGroceryItemView extends React.Component {
render() {
const {
values,
handleSubmit,
setFieldValue,
errors,
touched,
setFieldTouched,
isValid,
isSubmitting
} = this.props
return (
<Container>
<VepoHeader title={'Add Vegan Grocery Product'} />
<Container style={container}>
<ScrollView
keyboardShouldPersistTaps="always"
style={viewStyle(this.props.locationListDisplayed).scrollView}>
<LocationAutocomplete
label={'Grocery Store'}
placeholder={'Enter Grocery Store'}
setFieldTouched={setFieldTouched}
setFieldValue={setFieldValue}
name="GroceryStore"
required
error={errors.GroceryStore}
touched={touched.GroceryStore}
/>
<View style={viewStyle().detailsContainer}>
<Input
label={'Product Name'}
onTouch={setFieldTouched}
value={values.Name}
placeholder="Enter Name"
name="Name"
required
error={touched.Name && errors.Name}
deleteText={setFieldValue}
onChange={setFieldValue}
/>
<Input
label={'Product Brand'}
value={values.Brand}
onTouch={setFieldTouched}
error={touched.Brand && errors.Brand}
placeholder="Enter Brand"
name="Brand"
required
onChange={setFieldValue}
deleteText={setFieldValue}
/>
<View>
<Input
label={'Product Description'}
value={values.Description}
placeholder="Enter Description"
multiline={true}
required
onTouch={setFieldTouched}
error={touched.Description && errors.Description}
numberOfLines={4}
name="Description"
deleteText={setFieldValue}
onChange={setFieldValue}
/>
<Input
isValid={true}
isPrice={true}
label={'Product Price'}
value={values.Price}
onTouch={setFieldTouched}
error={touched.Price && errors.Price}
placeholder="Enter Price"
name="Price"
deleteText={setFieldValue}
onChange={setFieldValue}
/>
<CategoriesMultiselect.View
error={errors.Categories}
setFieldValue={setFieldValue}
setFieldTouched={setFieldTouched}
touched={touched.Categories}
name="Categories"
required
label="Product Categories"
categoryCodes={[CategoryEnums.CategoryCodes.Grocery]}
/>
<ImagePicker
label="Product Image"
setFieldValue={setFieldValue}
name="Image"
/>
</View>
</View>
</ScrollView>
</Container>
<Button.View
title="submit"
onPress={handleSubmit}
label={'GO!'}
disabled={!isValid || isSubmitting}
loading={isSubmitting}
/>
</Container>
)
}
}
const container = {
flex: 1,
...Spacing.horiz_pad_md_2,
backgroundColor: Colors.grey_lite,
flexDirection: 'column'
}
const formikEnhancer = withFormik({
validationSchema: Yup.object().shape({
Name: Yup.string().required(),
Brand: Yup.string().required(),
GroceryStore: Yup.object()
.shape({
city: Yup.string(),
latitude: Yup.number(),
longitude: Yup.number(),
name: Yup.string(),
place_id: Yup.string(),
street: Yup.string(),
street_number: Yup.string(),
suburb: Yup.string()
})
.required(),
Image: Yup.object().shape({
uri: Yup.string(),
name: Yup.string(),
type: Yup.string()
}),
Categories: Yup.array()
.min(1, 'Please select at least 1 Category')
.required(),
Description: Yup.string()
.min(9)
.required(),
Price: Yup.string().matches(
/^\d+(?:\.\d{2})$/,
'Price must contain 2 decimal places (cents) e.g. 4.00'
)
}),
isInitialValid: false,
mapPropsToValues: () => ({
Name: '',
Brand: '',
Description: '',
Price: '',
Categories: [],
GroceryStore: {},
Image: {}
}),
handleSubmit: (values, { props }) => {
handleSubmit(values, props)
},
displayName: 'AddGroceryItemView'
})(AddGroceryItemView)