Reputation: 420
I'm working on a personal project using React, in which I want to render a handful of components, each presenting data from different cities using Yahoo's weather API.
Initially, I was mapping over an array containing the cities I want data for, sending each city down to a component that makes the AJAX request, the result being 5-6 different components that each made their own call. That works fine if I just want to render current conditions or the high and low for several different cities.
But I would like to use React Router to give users the ability to click a city, causing a re-render that shows details and a 10-day forecast for that city only. The problem I'm running into is the current structure of the project. Because I'm mapping over the array of cities in the parent so I can pass that into the API URL, I'm stuck rendering all of the forecast components.
What would be a better way to structure the project and make the AJAX request so that one view is the several weather components and the other is the single detail view and 10-day forecast for that city?
class App extends Component {
PLACES = [
{ city: "chattanooga", state: "tn"},
{ city: "easton", state: "md"},
{ city: "new york", state: "ny"},
{ city: "norfolk", state: "va"},
{ city: "milford", state: "de"},
{ city: "bangkok", state: null}
]
render() {
return (
<div className="weather-container">
{
this.PLACES.map( (place, id) => {
return <Weather key={place.city} id={id} city={place.city}
state={place.state} />
})
}
</div>
)
}
}
export default App
So that's the parent component mapping over the PLACES
array to render the 6 <Weather />
components. And then in the <Weather />
component I'm making my AJAX request in componentDidMount()
componentDidMount() {
axios.get(`https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22${this.props.city}%2C%2$${this.props.state}%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys`)
.then(res => {
let data = res.data.query.results.channel;
this.setState({ data : data });
})
.catch( (error) => {
console.log(error);
})
}
Thanks for any direction!
Upvotes: 2
Views: 823
Reputation: 2090
Inside your Weather
component, you should have a <Link>
to a new component and the route would look like weather/:location
. The :location
notation means that you can accept anything here, like chattanooga
. If you need to pass both city and state, just do weather/:city/:state
This route will accept your params and you can then use those to re-call the API for the specific city you want to see and its 10-day forecast inside of your new component.
You can access the param inside of your new component by calling this.props.match.params.location
or this.props.match.params.city
, etc.
Upvotes: 0