Я учусь реагировать и пытаюсь построить карту с помощью mapbox. Я застрял в том, как отображать элементы отдельно.
В части рендеринга есть элемент <div/>
и компонент <CityWeather/>
в обертке. div
— ссылка на карту. <Cityweather />
— это информационное окно, которое должно отображать информацию о погоде в зависимости от широты и долготы. Метод рендеринга файла app.js
:
render(){
console.info(this.state);
return(
<section>
<div className = "map-container" ref = {x => { this.mapContainer = x;}}/>
<CityWeather lat = {this.state.lat} lng = {this.state.lng} />
</section>
);
componentDidMount()
это
componentDidMount() {
this.getLocation();
mapboxgl.accessToken = "";
const { lng, lat, zoom } = this.state;
const map = new mapboxgl.Map({
container: this.mapContainer,
style: "mapbox://styles/mapbox/streets-v11",
center: [lng, lat],
zoom: zoom
});
map.on("moveend", () => {
const { lng, lat } = map.getCenter();
this.setState({
lng: lng.toFixed(4),
lat: lat.toFixed(4),
zoom: map.getZoom().toFixed(2)
});
});
}
Компонент <CityWeather />
class CityWeather extends Component {
constructor(props) {
super(props);
this.state = {
name: ""
};
}
componentDidMount() {
console.info(this.props); // this logs only 1 time when the page loads
fetch("api?lat = " + this.props.lat +"&lon = " +this.props.lng + "&appid = ")
.then(res => res.json())
.then(data => {this.setState({ name: data.name });
}); // get name from lat and long and store it in state
}
render() {
return (
<div className = "city-weather">
<p>
City | <span className = "city">
{this.state.name}</span>
</p>
</div>
);
}
}
При каждом событии консоль регистрирует обновленные значения широты, долготы и масштабирования. Также <CityWeather/>
также отображается в первый раз. После этого компонент не отображается при изменении состояния.
@Mahmoodvcs Чего я пытаюсь добиться, так это отобразить только компонент `<CityWeather/>. Он отображается один раз только при перезагрузке страницы. Не при каждом изменении состояния.
используйте хук жизненного цикла shouldComponentUpdate, где вы можете проверить, какое изменение состояния вы хотите обновить в своем коде
Итак, проблема в том, что компонент <CityWeather/>
не отображается после изменения состояния? Или вы не хотите отображать его при изменении состояния? Или вы не хотите повторно отображать div при каждом изменении состояния?
@Mahmoodvcs Итак, проблема в том, что компонент <CityWeather/> не отображается после изменения состояния? да. Или вы не хотите повторно отображать div при каждом изменении состояния? Нет.
Что ж, если <CityWeather/>
не обновляется при изменении состояния, нам нужно увидеть его код. В текущем коде нет проблем.
@Mahmoodvcs Я обновил вопрос с помощью компонента <CItyWeather/>
Вы добавили журнал в прослушиватель? Я думаю, что метод не был вызван, потому что вы не двигались. вы можете использовать таймер и некоторые фиктивные данные для проверки рендеринга.
Вы загрузили данные о погоде в componentDidMount
. Он будет запускаться только при первом рендеринге компонента, а не при каждом изменении состояния.
Это правильный код:
class CityWeather extends Component {
constructor(props) {
super(props);
this.state = {
name: ""
};
}
componentDidMount() {
this.load();
}
load(){
console.info(this.props); // this logs only 1 time when the page loads
fetch("api?lat = " + this.props.lat + "&lon = " + this.props.lng + "&appid = ")
.then(res => res.json())
.then(data => {
this.setState({ name: data.name });
}); // get name from lat and long and store it in state
}
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.lat !== prevProps.lat || this.props.lng !== prevProps.lng) {
this.load();
}
}
render() {
return (
<div className = "city-weather">
<p>
City | <span className = "city">
{this.state.name}</span>
</p>
</div>
);
}
}
Я не понимаю проблемы. Можете ли вы объяснить немного больше? Вы хотите визуализировать дочерние компоненты отдельно? Или они не рендерятся?