【发布时间】:2019-09-19 21:47:39
【问题描述】:
我正在使用材料 ui react、redux-form、revalidate 和 mui-places-autocomplete 来实现使用 google places API 的自动完成组件。我已经设法实现了地点查找,但我似乎无法像处理其他输入一样进行错误处理。
此外,每当我在字段中输入内容并从下拉列表中选择一个位置时,清除该字段并单击它,它会重置为它的最后一个值,而不是将该字段留空并显示错误。
我尝试使用 react-places 自动完成,它按预期工作,但它缺乏我需要的材料设计,所以这不是一个真正的选择。
由于 mui-places-autocomplete 有几个道具,包括 textFieldProps 应该有一种方法可以利用文本字段中的错误道具并使用它,但我不知道该怎么做。
这是我的代码,以防它有助于显示我想要完成的工作。
PlaceInput.jsx
import React, { Component } from 'react';
import MUIPlacesAutocomplete from 'mui-places-autocomplete';
import Script from 'react-load-script';
/* MUI Components */
import FormControl from '@material-ui/core/FormControl';
import FormHelperText from '@material-ui/core/FormHelperText';
class PlaceInput extends Component {
state = {
scriptLoaded: false
}
handleScriptLoad = () => {
this.setState({
scriptLoaded: true
})
}
render() {
const { onSuggestionSelected, createAutocompleteRequest, meta: { touched, error }, ...other } = this.props;
return (
<FormControl error={touched && !!error} margin="normal" fullWidth>
<Script
url="https://maps.googleapis.com/maps/api/js?key=API_KEY&libraries=places"
onLoad={this.handleScriptLoad}
/>
{
this.state.scriptLoaded &&
<MUIPlacesAutocomplete
onSuggestionSelected={onSuggestionSelected}
createAutocompleteRequest={createAutocompleteRequest}
renderTarget={() => (<div />)}
textFieldProps={{ ...other }}
/>
}
{
touched &&
error &&
<FormHelperText style={{ color: '#f44336' }}>{error}</FormHelperText>
}
</FormControl>
)
}
}
export default PlaceInput;
EventForm.jsx
/*global google*/
import { reduxForm, Field } from 'redux-form';
import { composeValidators, combineValidators, isRequired, hasLengthGreaterThan } from 'revalidate';
import { geocodeBySuggestion } from 'mui-places-autocomplete';
/* Form Inputs */
import PlaceInput from '../../../app/common/form/PlaceInput';
const validate = combineValidators({
title: isRequired({ message: 'The event title is required' }),
category: isRequired({ message: 'Please provide a category' }),
description: composeValidators(
isRequired({ message: 'Please enter a description' }),
hasLengthGreaterThan(4)({ message: 'Description needs to be at least 5 characters' })
)(),
city: isRequired('City'),
venue: isRequired('Venue'),
date: isRequired('Date')
});
class EventForm extends Component {
state = {
cityLatLng: {},
venueLatLng: {},
scriptLoaded: false
}
createAutocompleteRequestForCities = (inputValue) => {
return {
input: inputValue,
types: ['(cities)']
}
}
createAutocompleteRequestForEstablishments = (inputValue) => {
return {
input: inputValue,
types: ['establishment'],
location: new google.maps.LatLng(this.state.cityLatLng),
radius: 1000
}
}
handleScriptLoad = () => {
this.setState({
scriptLoaded: true
})
}
render() {
const { classes, invalid, submitting, pristine } = this.props;
return (
<form onSubmit={this.props.handleSubmit(this.onFormSubmit)}>
<Field
fullWidth
onSuggestionSelected={this.onSuggestionSelectedCity}
createAutocompleteRequest={this.createAutocompleteRequestForCities}
name="city"
helperText="Required field"
component={PlaceInput}
label="Event City"
/>
{
this.state.scriptLoaded &&
<Field
fullWidth
onSuggestionSelected={this.onSuggestionSelectedVenue}
createAutocompleteRequest {this.createAutocompleteRequestForEstablishments}
name="venue"
helperText="Required field"
component={PlaceInput}
label="Event Venue"
/>
}
)
}
}
EventForm.propTypes = {
classes: PropTypes.object.isRequired,
};
const mapStateToProps = (state, ownProps) => {
const eventId = ownProps.match.params.id;
let event = {};
if (eventId && state.events.length > 0) {
event = state.events.filter(event => event.id === eventId)[0];
}
return {
initialValues: event
}
}
const actions = {
createEvent,
updateEvent,
deleteEvent
}
export default compose(
connect(mapStateToProps, actions),
reduxForm({ form: 'reduxForm', enableReinitialize: true, validate }),
withStyles(styles)
)(EventForm);
【问题讨论】:
-
考虑清理您的代码,以便读者可以专注于手头的问题。
-
谢谢你的建议,我试试。我只是想尽可能清楚地解决问题。
标签: javascript reactjs autocomplete google-places-api material-ui