Новичок в кодировании, я пытаюсь создать панель поиска для карты Google, где ввод запроса (в Search. js) приведет к тому, что маркеры будут отфильтрованы в соответствии с тем, что введено (в Map. js).
Я получаю обратно отфильтрованный массив (filterList) нормально, но когда я пытаюсь установить его в любое состояние (place или newPlaces), он возвращается с бесконечным l oop.
Заранее благодарим.
Приложение. js
import Map from './components/map/Map';
import Navbar from './components/Navbar';
class App extends Component {
constructor(props) {
super(props);
this.state = {
letters: '',
newPlaces: '',
places: [
{
name: "PL",
lat: 51.510228,
lng: -0.132992,
type: "alive"
},
...
]
}
this.searchState=this.searchState.bind(this)
};
// set the state of letters to match the Search.js input field
searchState = (e) => {
this.setState({letters: e}, this.handleSubmit)
}
// compare the filtered array with the original array in state and kick out the members of state.places that are missing in the filtered array
searchAdjustedArray = () => {
const filteredList = this.state.places.filter(club =>
club.name.toUpperCase().includes(this.state.letters.toUpperCase())
);
// here, is where either the places array must be ammended and pasted into Map as prop, or a new array - newPlaces, must be ammended, and passed as props into map.. infinit loops
this.setState({ newPlaces: filteredList })
}
render() {
return (
<div>
<Navbar
childMethodToChangeState={this.searchState}
/>
{this.searchAdjustedArray()}
<Map
markers={this.state.newPlaces}
/>
</div>
);
}
}
export default App;
где поле ввода является компонентом панели навигации. js
import Search from '../components/Search';
const Navbar = ({ childMethodToChangeState }) => {
return (
<nav className="d-flex navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="www.sassyladancer.com">Sassy's</a>
<button className="navbar-toggler"
type="button"
data-toggle="collapse"
data-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle Navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav mr-auto">
<li className="nav-item">
<a className="nav-link" href="#">Reviews</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Testimonials</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Special Offers</a>
</li>
</ul>
<form className="form-inline my-2 my-lg-0">
<Search
childMethodToChangeState={childMethodToChangeState}
/>
<button className="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
);
}
export default Navbar;
Поиск . js
const Search = ({ childMethodToChangeState }) => {
const [text, setText] = useState('')
const searchChange = (q) => {
setText(q)
childMethodToChangeState(q)
}
return (
<section className='search'>
<form>
<input
type='text'
className='form-control'
placeholders='Search Clubs'
value={text}
onChange={(e) => searchChange(e.target.value)}
autoFocus
/>
</form>
</section>
)
}
export default Search;
Карта. js
import React, { Component } from 'react';
import { compose, withProps } from 'recompose';
import {
withScriptjs,
withGoogleMap,
GoogleMap,
Marker,
} from 'react-google-maps';
import icon1 from '../map/icon1.svg';
import iconDead from '../map/iconDead.svg';
const API = 'AIzaSyD_INqSpFnl3D3qLAq-jomYcYkztdUbCk0';
const MapWithMarkers = compose(
withProps({
googleMapURL: `https://maps.googleapis.com/maps/api/js?key=${API}&callbak=initMap`,
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `800px` }} />,
mapElement: <div style={{ height: `100%` }} />,
}),
withScriptjs,
withGoogleMap,
)((props) =>
<GoogleMap
center={{ lat: 51.510228, lng: -0.132992 }}
zoom={10}
defaultOptions={{
styles: mapStyles
}}
>
{props.markers.map(place => {
return (
<MarkerWithSearch
key={place.id}
position={{ lat: place.lat, lng: place.lng }}
content={place.name}
icon={place.type}
/>
);
})}
</GoogleMap>
);
class MarkerWithSearch extends Component {
constructor() {
super();
this.state = {
isOpen: false
}
this.onToggleOpen = this.onToggleOpen.bind(this);
}
onToggleOpen() {
this.setState({
isOpen: !this.state.isOpen
});
}
render() {
return (
<Marker
id={this.props.id}
position={this.props.position}
onClick={this.onToggleOpen}
icon={ this.props.icon === "alive" ?
({
url: icon1,
scaledSize: new window.google.maps.Size(45, 45)
}) :
({
url: iconDead,
scaledSize: new window.google.maps.Size(45, 45)
})}
>
</Marker>
)
}
}