Я пытаюсь создать компонент выбора в React, который будет иметь аналогичный api, что и элемент выбора html5.
Учти это:
<select>
<option value = "one"> One </option>
<option value = "two" selected> Two </option>
<option value = "three"> Three </option>
</select>
selectedOption будет состоянием в элементе React Select верхнего уровня.
...
Class Select extends React.Component {
state = { selectedOption: //how do i get this value? };
...
при щелчке дочернего элемента я могу вызвать родительскую функцию, чтобы активировать / выбрать дочерний элемент
<Option onClick = {this.props.select}> ...
Я просто не уверен, как определить начальное значение selectedOption из дочернего свойства selected.
должен ли я установить родительское состояние из дочернего componentDidMount(), проверив, есть ли у ребенка опора selected, а затем позвонив this.props.select()?
ИЛИ
следует ли мне проверить дочернюю опору в родительской функции render, сопоставив все children и затем установив родительское состояние на его основе? (что было бы побочным эффектом)
ИЛИ есть лучший способ справиться с этим? Как это обычно делается в таких сценариях?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Обновите свое состояние
Обновите свое состояние, чтобы selectedOption был равен null. Ваше состояние должно выглядеть так:
state = {
selectedOption: null,
};
Создайте функцию handleChangeEvent
Создайте функцию, которая будет обрабатывать изменение, когда пользователь изменяет свой параметр, и соответствующим образом обновлять состояние.
handleChangeEvent = selectedOption => {
this.setState({ selectedOption }); //this sets selectedOption to an object containing the value and input of the selection
//if you want to get the value and the input and store those in separate variables you can do this
const labelValue = selectedOption.label // this gets whatever label you assigned to labelValue
const valueOfOption = selectedOption.value //this gets the value of the option and assigns it to valueOfOption
}
Очевидно, вы можете обновить переменные state вместо создания экземпляров двух новых переменных (labelValue и valueOfOption).
Обновить функцию рендеринга
Обновите свою функцию рендеринга, чтобы вызвать изменение дескриптора при изменении. Обновите ваш текущий источник. Вот это у вас:
<Option onClick = {this.props.select()}>
Кстати, эта функция select() будет вызываться таким образом независимо от щелчка. Правильный способ сделать это: onClick = {() => this.props.select()}.
Вы бы хотели этого:
<Option onClick = {this.handleChangeEvent}> //should this be onChange? not sure how your Option component is set up though
Теперь, если ваша функция select() является функцией, переданной через props (что, похоже, так), вам необходимо обработать selectedOption в вашем родительском компоненте. Вы не поделились большой информацией о своем родительском компоненте, поэтому я проигнорировал функцию select() и создал handleChangeEvent().
Собрав все это вместе, у вас должно получиться что-то вроде этого:
//necessary imports
class Select extends Component {
state = {
selectedOption: null,
}
handleChangeEvent = selectedOption => {
this.setState({ selectedOption });
const labelValue = selectedOption.label;
const valueOfOption = selectedOption.value;
}
render() {
const { selectedOption } = this.state;
return (
<div>
<Option value = {selectedOption} onClick = {this.handleChangeEvent} />
</div>
)
}
}
export default Select;
Это должно быть так.
Дополнительная помощь
Есть пара пакетов реагирования, которые делают всю эту работу за вас. Я бы посоветовал изучить их, чтобы вам не пришлось изобретать велосипед. Первое, что приходит на ум, - это React Select v2. Вы можете посетить сайт здесь (необработанная ссылка: https://react-select.com/home). Я бы посоветовал просмотреть примеры и документацию.
Установка для React Select: npm i react-select или yarn add react-select
.
Есть и другие, такие как rc-select или react-virtualized-select и другие. Вы можете изучить их и увидеть, какой из них лучше всего подходит для ваших нужд, или просто продолжить разработку своего собственного.
Надеюсь это поможет.
так вы передаете функцию от родителя к ребенку? и вы хотите вызвать эту функцию в своем дочернем компоненте и передать это значение обратно своему родителю? правильно ли я это понимаю?
Я хочу установить родительское состояние на основе дочерней опоры, а не на событии щелчка, а только на исходной родительской визуализации. когда компонент отрисовывается в первый раз, родителю необходимо проверить, есть ли у какого-либо из дочерних элементов атрибут «selected», и установить его состояние на основе значения этого атрибута. Это только начальное состояние, с тех пор состояние может изменяться в зависимости от того, на каком дочернем элементе был щелкен мышью.
В итоге я установил начальное состояние родителя в componentDidMount родителя следующим образом:
componentDidMount() {
const { children } = this.props;
let selectedOption = null;
// check if child elements have a 'selected' attribute and set state based on it
React.Children.map(children, (child, index) => {
if (child.props.selected) {
selectedOption = index;
}
});
this.setState({ selectedOption });
}
Спасибо за подробный ответ. Это не решает мою проблему получения начального родительского состояния от дочернего при рендеринге. У детей может быть свойство 'selected', которое решает, каково значение 'selectedOption', как мы с этим справимся? (Я понимаю как это сделать на клике)