Как получить значения состояния из пользовательского компонента в другой родительский компонент
У меня есть 2 класса (оба React.Component). Допустим, один из них - мой собственный компонент, который также построен на другом пользовательском компоненте (в моем случае это автозаполнение React Places). Просто посмотрите на эту картину
Код здесь:
//App.js
import React, { Component } from 'react';
import './App.css';
import PlaceAutocomplete from "./places_autocomplete";
class App extends Component {
constructor(props) {
super(props);
this.state = { output: '' };
}
render() {
return (
<div className="App">
<PlaceAutocomplete/>
<p>{this.state.output}</p>
</div>
);
}
}
export default App;
//places_autocomplete.js
import React, { Component } from 'react';
import './PlaceAutocomplete.css';
import PlacesAutocomplete from 'react-places-autocomplete';
class PlaceAutocomplete extends Component {
constructor(props) {
super(props);
this.state = { address: '', output: '' };
}
handleChange = address => {
this.setState({ address });
};
handleSelect = async address => {
this.setState({address: address});
this.state.output = address;
document.getElementById('lsi').blur();
};
searchOptions = {
types: ['(cities)']
};
hidden = (suggest) => {
return suggest == null || suggest === ""
? "autocomplete-dropdown-container-hidden"
: "autocomplete-dropdown-container";
};
render() {
return (
<PlacesAutocomplete
value={this.state.address}
onChange={this.handleChange}
onSelect={this.handleSelect}
searchOptions={this.searchOptions}>
{({ getInputProps, suggestions, getSuggestionItemProps, loading }) => (
<div>
<input value={this.state.address}
id={'lsi'}
{...getInputProps({
placeholder: 'Select a city',
className: 'location-search-input',
})}/>
<div className={this.hidden(suggestions[1])}>
{loading && <div>Loading...</div>}
{suggestions.map(suggestion => {
const className = suggestion.active
? "suggestion-item--active"
: "suggestion-item";
// inline style for demonstration purpose
const style = suggestion.active
? { backgroundColor: '#fafafa', cursor: 'pointer' }
: { backgroundColor: '#ffffff', cursor: 'pointer' };
return (
<div
{...getSuggestionItemProps(suggestion, {
className: className,
style,
})}
>
<span>{suggestion.description}</span>
</div>
);
})}
</div>
</div>
)}
</PlacesAutocomplete>
);
}
}
export default PlaceAutocomplete;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Итак, вы можете видеть, как я пытался найти решение для этого. Этот код в основном выглядит некрасиво, потому что я не знаю другого способа реализации этих возможностей.
Системная информация:
- Последний React для 17.08.2018 (я не помню, но знаю, что это последний (я установил его всего 1 неделю назад).
- Это приложение, созданное с помощью шаблона CRA (Create React Application). Поэтому, пожалуйста, если ваше решение не будет работать с этим шаблоном (я думаю, что есть другие стили, такие как ES6 и т. Д., Но это не главное), добавьте хотя бы объяснение к вашему ответу.
1 ответ
Попробуйте поднять состояние до родительского компонента и использовать обратные вызовы для обмена данными. Как указано в документации для реагирования, в приложении React должен быть единый "источник правды" для изменений данных - это уменьшает потенциальные ошибки и дублирующий код. Взгляни на. https://reactjs.org/docs/lifting-state-up.html