У меня проблемы с настройкой состояния компонента в React. Компонент называется «Поиск» и использует реакцию-выбор. Полный компонент находится здесь:
class Search extends React.Component {
constructor(props){
super(props);
let options = [];
for (var x in props.vals){
options.push({ value: props.vals[x], label: props.vals[x], searchId: x });
};
this.state = {
inputValue: '',
value: options
};
}
handleChangeEvent = (value: any, actionMeta: any) => {
if (actionMeta.action == "remove-value"){
this.props.onRemoveSearch({ searchId: actionMeta.removedValue.searchId })
}
this.setState({ value });
};
handleInputChange = (inputValue: string) => {
this.setState({ inputValue });
};
handleSearch = ({ value, inputValue }) => {
this.setState({
inputValue: '',
value: [...value, createOption(inputValue)], // Eventually like to take this out...
});
this.props.onSearch({ inputValue });
}
handleKeyDown = (event: SyntheticKeyboardEvent<HTMLElement>) => {
const { inputValue, value } = this.state;
if (!inputValue) return;
switch (event.key) {
case 'Enter':
case 'Tab':
this.handleSearch({
value,
inputValue
});
event.preventDefault();
}
};
render() {
const { inputValue, value } = this.state;
return (
<div className = "search">
<div className = "search__title">Search</div>
<Tooltip
content = {this.props.tooltipContent}
direction = "up"
arrow = {true}
hoverDelay = {400}
distance = {12}
padding = {"5px"}
>
<CreatableSelect
className = {"tags"}
components = {components}
inputValue = {inputValue}
isMulti
menuIsOpen = {false}
onChange = {this.handleChangeEvent}
onInputChange = {this.handleInputChange}
onKeyDown = {this.handleKeyDown}
placeholder = "Add filters here..."
value = {value}
/>
</Tooltip>
</div>
);
}
}
module.exports = Search;
Вы, наверное, заметили странную вещь, которую я делаю в функции конструктора. Это потому, что мне нужно использовать данные из моей базы данных firebase, которая находится в объектной форме, но response-select ожидает массив объектов со свойством «значение» и «метка». Вот как выглядят мои данные:
Чтобы восполнить пробел, я написал цикл for-in, который создает массив (называемый параметрами) и передает его в state.value.
Проблема: поскольку я использую этот цикл «for in», React не распознает, когда свойства были изменены. Таким образом, компонент response-select не перерисовывается. Как передать эти реквизиты (либо изменить их внутри родительского компонента, либо в компоненте поиска), чтобы компонент поиска повторно отобразил?



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


Я бы посоветовал не использовать состояние value. Вы просто копируете реквизит в свое состояние. Вы можете напрямую использовать props в методе render().
Я считаю, что вы используете состояние value, потому что вам нужно обновлять его на основе действий пользователя. В этом случае вы можете поднять это состояние до родительского компонента.
class Parent extends React.Component {
constructor() {
this.state = { value: //structure should be the same as props.vals in ur code };
}
render() {
return (
<Search vals = {this.state.value}/>
);
}
}
class Search extends React.Component {
constructor(props){
super(props);
this.state = {
inputValue: '',
};
}
render() {
const { inputValue } = this.state;
const { vals } = this.props;
let options = [];
for (var x in vals){
options.push({ value: vals[x], label: vals[x], searchId: x });
};
return (
<div className = "search">
<div className = "search__title">Search</div>
<Tooltip
content = {this.props.tooltipContent}
direction = "up"
arrow = {true}
hoverDelay = {400}
distance = {12}
padding = {"5px"}
>
<CreatableSelect
value = {options}
/>
</Tooltip>
</div>
);
}
}
module.exports = Search;
Да, я использую состояние значения, потому что на него полагается компонент response-select. Не могли бы вы привести краткий пример того, что вы подразумеваете под «поднятием» состояния до моего родительского компонента? Как я мог этого добиться? Спасибо.
Многие вещи зависят от состояния "значения" в моем компоненте поиска, поэтому я немного не понимаю, как его поднять.
Пожалуйста, посмотрите мой обновленный ответ для краткой демонстрации. Без понимания кода ur я не могу предоставить рабочую демонстрацию. Вам также может потребоваться обновить функции обработчика событий.
Если ваш компонент не размонтируется, конструктор не будет перезапущен. Таким образом, ваш цикл for in не будет перезапущен, если он не будет отключен. Другой вариант - переместить параметры в метод рендеринга или добавить дополнительный метод жизненного цикла componentDidUpdate.