Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
28
rated 0 times [  29] [ 1]  / answers: 1 / hits: 19458  / 7 Years ago, thu, december 28, 2017, 12:00:00

Need help with react...
Trying to implement a collapsible list of cards with weather information.
Already implemented the behavior of expand and collapse, but when i clicked on one panel the other panel open at the same time (i have 2 panels and need 7 to display weahter for 7 days of the week).



How can i open and close just one panel?



Code:



import React, { Component } from 'react';
import Moment from 'react-moment';

import RandomGif from './RandomGif.js';

const urlForCity = city => `https://cors-anywhere.herokuapp.com/http://api.openweathermap.org/data/2.5/forecast/daily?q=${city}&units=metric&cnt=7&appid=1fba7c3eaa869008374898c6a606fe3e`

class OpenWapi extends Component {
constructor(props) {
super(props);
this.state = {
requestFailed: false,
shown: false
}
this.componentDidMount = this.componentDidMount.bind(this);
this.toggle = this.toggle.bind(this);
}

componentDidMount() {
fetch(urlForCity(this.props.city))
.then(response => {
if(!response.ok) {
throw Error(Network request failed)
}
return response;
})
.then(data => data.json())
.then(data => {
this.setState({
weatherData: data
})
}, () => {
this.setState({
requestFailed: true
})
})
}

toggle() {
this.setState({
shown: !this.state.shown
});
}

render() {

if(this.state.requestFailed) return <p>Request Failed.</p>;
if(!this.state.weatherData) return <p>Loading...</p>;

return (
<div>
<p>City: {this.state.weatherData.city.name}</p>

{/* Day 1 */}
<div onClick={this.toggle} className=dayWeekItem>
<div className=top-content>
<div className=icon-weather></div>
<div className=date>
<div className=weekday>Today</div>
<div className=day-long><Moment unix format=MMM DD YYYY>{this.state.weatherData.list[0].dt}</Moment></div>
</div>
<div className=temperature>
<div className=temp-high>{parseInt(this.state.weatherData.list[0].temp.max)}º</div>
<div className=temp-low>{parseInt(this.state.weatherData.list[0].temp.min)}º</div>
</div>
</div>
<div className={this.state.shown ? toggleContent-open : toggleContent-closed} >
<div className=weather-gif >
<RandomGif keyword={this.state.weatherData.list[0].weather[0].description} />
</div>
</div>
</div>



{/* Day 2 */}
<div onClick={this.toggle} className=dayWeekItem>
<div className=top-content>
<div className=icon-weather></div>
<div className=date>
<div className=weekday>Tomorrow</div>
<div className=day-long><Moment unix format=MMM DD YYYY>{this.state.weatherData.list[1].dt}</Moment></div>
</div>
<div className=temperature>
<div className=temp-high>{parseInt(this.state.weatherData.list[1].temp.max)}º</div>
<div className=temp-low>{parseInt(this.state.weatherData.list[1].temp.min)}º</div>
</div>
</div>
<div className={this.state.shown ? toggleContent-open : toggleContent-closed} >
<div className=weather-gif >
<RandomGif keyword={this.state.weatherData.list[1].weather[0].description} />
</div>
</div>
</div>

{/* Day 3 */}


{/* Day 4 */}


{/* Day 5 */}


</div>
)
}
}

export default OpenWapi;

More From » reactjs

 Answers
27

I would have an object to represent the state, a field for each panel.



Like this:



constructor(props) {
...
this.state = {
requestFailed: false,
shown: {}
}
...
}

...

toggle(panelNumber) {
this.setState({
shown: {
...this.state.shown,
[panelNumber]: !this.state.shown[panelNumber]
}
});
}

...


The toogle function is used like this, for instance, Day 1:



<div onClick={() => this.toggle(1)} className=dayWeekItem>
...
</div>


And to show in html, for instance, Day 1:



      <div className={this.state.shown[1] ? toggleContent-open : toggleContent-closed} >
<div className=weather-gif >
<RandomGif keyword={this.state.weatherData.list[0].weather[0].description} />
</div>
</div>

[#55583] Friday, December 22, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
elvisissacg

Total Points: 410
Total Questions: 108
Total Answers: 121

Location: Monaco
Member since Tue, Jun 16, 2020
4 Years ago
;