По какой-то причине мое поле GroceryStore
никогда не добавляется к объекту props.errors
formik, несмотря ни на что.Это обязательное поле, так что может быть причиной того, что это поле никогда не будет добавлено в объект formik props.errors
, когда поле не определено?GroceryStore
действительно появляется в объектах props.touched
и props.values
formik.
Поле задается в <LocationAutocomplete
в коде ниже:
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)
// $FlowFixMe
const AddGroceryItemViewComponent = connect(
mapStateToProps,
mapDispatchToProps
)(formikEnhancer)
export default AddGroceryItemViewComponent
Я недумаю, что необходимо увидеть реализацию LocationAutocomplete
, потому что мы должны увидеть ошибку в props.errors
для GroceryStore
независимо от того, что, если значение не введено.Но тут все равно:
let PresentationalLocationView = (props: PresentationalLocationViewProps) => {
return (
<View>
<Input
isValid={props.isValid}
placeholder={props.placeholder}
label={props.label}
value={props.location.searchText}
required
name={props.name}
error={props.touched && props.error}
onTouch={props.setFieldTouched}
onChange={(name, text) => {
props.onChange(text)
if (!text) {
props.updateLocationAutocompletePlace({})
props.updateShopShouldHideResults(true)
props.updateLocationListDisplayed(false)
}
}}
deleteText={() => {
props.onChange('')
props.updateLocationAutocompletePlace({})
props.updateShopShouldHideResults(true)
props.updateLocationListDisplayed(false)
}}
/>
<View style={autocompleteStyle.listView(props)}>
<FlatList
keyboardShouldPersistTaps={true}
data={props.autocompleteResults.predictions}
renderItem={(listItemValue) =>
renderAutocompleteItem(props, listItemValue)
}
/>
</View>
</View>
)
}
// eslint-disable-next-line flowtype/no-weak-types
class ShopView extends React.Component<LocationViewProps | any> {
componentDidUpdate(prevProps) {
if (!isEqual(this.props.locationValue, prevProps.locationValue)) {
this.setFormLocation(this.props)
}
}
setFormLocation = (props) => {
if (props && props.setFieldValue) {
props.setFieldValue(props.name, props.locationValue)
}
}
render(): React.Node {
return (
// $FlowFixMe
<PresentationalLocationView
value={this.props.location.searchText}
location={this.props.location}
placeholder={this.props.placeholder}
isValid={this.props.isValid}
label={this.props.label}
required
name={this.props.name}
touched={this.props.touched}
error={this.props.error}
setFieldTouched={this.props.setFieldTouched}
onTouch={this.props.onTouch}
updateLocationAutocompletePlace={
this.props.updateLocationAutocompletePlace
}
updateShopShouldHideResults={this.props.updateShopShouldHideResults}
updateLocationListDisplayed={this.props.updateLocationListDisplayed}
autocompleteResults={this.props.location.searchResults}
shouldHideResults={this.props.location.shouldHideResults}
onListItemSelect={(shop) => {
this.props.getLocationAutocompletePlaceDetails(shop.place_id)
this.props.updateLocationAutocompleteSearchText(shop.description)
this.props.updateShopShouldHideResults(true)
this.props.updateLocationListDisplayed(false)
}}
onChange={(text) => onChange(this.props, text)}
/>
)
}
}