我有一个搜索栏(父级),其中有3个子项-位置下拉列表,日历(日期选择器)和持续时间下拉列表。默认情况下,位置会选择为用户所在的位置。我希望将焦点更改为日期选择器,其中日历下拉列表在与第一个下拉列表(位置下拉列表)进行交互之后自动打开,并且从第二个输入到第三个输入也是如此。我该怎么做呢?
父母:
import React, { Component } from 'react';
import { Icon, Btn } from '@appearhere/bloom';
import Title from '../Title';
import LocationDropdown from '../LocationDropdown';
import AppearDateCalendar from '../AppearDateCalendar';
import DurationDropdown from '../DurationDropdown';
import css from './SegmentationBar.css';
import i18n from 'utils/i18n/i18n';
const t = i18n.withPrefix('client.apps.static.screens.home.header.segmentation');
type Props = {
onLocationDropdownChange: Function,
onDateChange: Function,
onDurationChange: Function,
onSubmit: Function,
onMobileSearchClick: Function,
fullSupport: boolean,
};
export default class SegmentationBar extends Component<Props> {
render() {
const {
onLocationDropdownChange,
onDateChange,
onDurationChange,
onSubmit,
fullSupport,
} = this.props;
return (
<div className={css.container}>
<Title />
{fullSupport && (
<div className={css.barWrapper}>
<div className={css.segmentationBar}>
<LocationDropdown onDropdownChange={onLocationDropdownChange} />
<AppearDateCalendar onDateChange={onDateChange} />
<DurationDropdown onDropdownChange={onDurationChange} />
</div>
<div className={css.submitButton} onClick={onSubmit}>
<Icon name="search" />
</div>
</div>
)}
</div>
);
}
}
孩子:
第一个下拉列表:
import React, { Component } from 'react';
import i18n, { getCurrentLocale } from 'utils/i18n/i18n';
import { Icon } from '@appearhere/bloom';
import locationOrder from './locationOrder.json';
import locations from './locations.json';
import css from './LocationDropdown.css';
const t = i18n.withPrefix('client.apps.static.screens.home.header.segmentation.location');
type Props = {
onDropdownChange: Function,
};
type Location = {
key: string,
name: string,
country: string,
placeId: string,
searchString: string,
priority: number,
};
class LocationDropdown extends Component<Props> {
componentDidMount() {
const selectedCity = this.findCitiesForCountry(locationOrder[getCurrentLocale()][0])[0];
this.props.onDropdownChange(selectedCity.searchString, selectedCity.placeId);
}
citySorting = (a: Location, b: Location): number => {
if (a.priority > b.priority) return 1;
if (a.priority < b.priority) return -1;
if (a.name >= b.name) return 1;
return -1;
};
findCitiesForCountry = (countryKey: string): Array<Location> =>
locations
.filter((location: Location): boolean => location.country === countryKey)
.sort(this.citySorting);
handleDropdownChange = (event: SyntheticInputEvent<EventTarget>) => {
const city = locations.find(
(location: Location): boolean => location.key === event.target.value,
);
this.props.onDropdownChange(city.searchString, city.placeId);
};
renderSelectOptions = (countryKey: string): React.Node => {
const cities = this.findCitiesForCountry(countryKey);
return cities.map((city: Location): React.Node => (
<option key={city.key} value={city.key}>
{city.name}
</option>
));
};
renderSelectOptionGroups = (): React.Node =>
locationOrder[getCurrentLocale()].map((countryKey: string): React.Node => (
<optgroup key={countryKey} label={t(countryKey)}>
{this.renderSelectOptions(countryKey)}
</optgroup>
));
render() {
return (
<div className={css.LocationDropdown}>
<div className={css.searchIcon}>
<Icon name="search" />
</div>
<select role="listbox" className={css.locationSelect} onChange={this.handleDropdownChange}>
{this.renderSelectOptionGroups()}
</select>
</div>
);
}
}
第二个输入: 日历:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import i18n from 'utils/i18n/i18n';
import { DayPicker } from '@appearhere/bloom';
import moment from 'utils/moment/moment';
import cx from 'classnames';
import css from './AppearDateCalendar.css';
const t = i18n.withPrefix('client.apps.static.screens.home.header.segmentation.calendar');
type Props = {
onDateChange: Function,
};
type State = {
calendarOpen: boolean,
month: moment,
day: ?moment,
};
export default class AppearDateCalendar extends Component<Props, State> {
state = {
calendarOpen: false,
month: moment(),
day: undefined,
};
componentDidMount() {
document.addEventListener('mousedown', this.handleClickOutside);
}
componentWillUnmount() {
document.removeEventListener('mousedown', this.handleClickOutside);
}
handleClickOutside = (event: SyntheticMouseEvent<EventTarget>) => {
const currentNode = ReactDOM.findDOMNode(this);
if (currentNode && !currentNode.contains(event.target)) {
this.setState({ calendarOpen: false });
}
};
handleCalendarClick = () => {
this.setState({ calendarOpen: !this.state.calendarOpen });
};
handleMonthChange = (_event: any, newMonth: moment) => {
this.setState({ month: newMonth });
};
handleDaySelect = (_event, day: moment) => {
this.props.onDateChange(day);
this.setState({ day, calendarOpen: false });
};
dateDisplayText = (): string => {
if (this.state.day) return this.state.day.format('Do MMM, YY');
return t('choose_date');
};
render() {
return (
<div className={cx(css.appearDateCalendar, this.state.calendarOpen ? css.focused : '')}>
<div onClick={this.handleCalendarClick}>
<h5 className={css.heading}>{t('heading')}</h5>
<p className={css.dateText}>{this.dateDisplayText()}</p>
</div>
{this.state.calendarOpen && (
<div className={css.calendarDropdown}>
<DayPicker
month={this.state.month}
onInteraction={this.handleDaySelect}
onMonthChange={this.handleMonthChange}
/>
</div>
)}
</div>
);
}
}
第三个下拉列表: 持续时间:
import React, { Component } from 'react';
import i18n from 'utils/i18n/i18n';
import css from './DurationDropdown.css';
import durations from './durations.json';
const t = i18n.withPrefix('client.apps.static.screens.home.header.segmentation.duration');
type Props = {
onDropdownChange: Function,
};
type Duration = {
name: string,
maxDuration: number,
highValue: boolean,
};
export default class DurationDropdown extends Component<Props> {
handleDropdownChange = (event: SyntheticInputEvent<EventTarget>) => {
const durationIndex = event.target.value;
const duration = durations[durationIndex];
this.props.onDropdownChange(duration.maxDuration, duration);
};
renderDurationOptions = (): React.Node =>
durations.map((duration: Duration, index: number): React.Node => (
<option key={duration.name} value={index}>
{t(duration.name)}
</option>
));
render() {
return (
<div className={css.durationDropdown}>
<h5 className={css.heading}>{t('heading')}</h5>
<select role="listbox" className={css.durationSelect} onChange={this.handleDropdownChange}>
<optgroup label={t('booking_duration')}>{this.renderDurationOptions()}</optgroup>
</select>
</div>
);
}
}
答案 0 :(得分:0)
您应该阅读有关React引用的信息:http://parseplatform.org/Parse-SDK-JS/api/2.2.1/Parse.Query.html#select
您可以为每个输入创建一个ref
,并将其从您的父级传递给3个孩子,并在下拉菜单处理程序中使用ref.current.focus()
。