Reputation: 1095
I have a map app I built that requires some map icons to appear/disappear after a button press, but I can't figure out how to set it to re-render the component when I pass in a new sports property from it's parents component :
Parent loads component:
<SimpleMap sports=[default value and future values go here] />
Simple map component(simplified):
constructor(props) {
(props);
this.state = {
events: [{venue: {lat: 2, lon: 1}}],
sports: ["baseball", "football", "paddle", "soccer", "boxing", "dart", "biking", "golf", "hockey", "inline-skating", "tennis", "volleyball", "skateboard", "kickball", "bowling", "pool", "ride", "hike", "ice-skating"]
};
};
componentWillReceiveProps (nextProps) {
this.setState({events: [{venue: {lat: 2, lon: 1}}],
sports: nextProps.sports});
console.log(nextProps.sports);
}
static defaultProps = {
center: {lat: 36.160338, lng: -86.778780},
zoom: 12,
sports: ["baseball", "football", "paddle", "soccer", "boxing", "dart", "biking", "golf", "hockey", "inline-skating", "tennis", "volleyball", "skateboard", "kickball", "bowling", "pool", "ride", "hike", "ice-skating"],
};
makeMapEvents (insertProps) {
fetch("./json/meetup.json").then((response) => {
return response.json()
}).then((response) => {
/* eventually returns new events object based on insertProps */
this.setState({events: response});
}
};
componentDidMount () {
this.makeMapEvents(this.state.sports);
console.log("mounted", this.state.sports);
}
Eventually ends up here to map events from state:
<GoogleMap>
{this.state.events.map((result) => {
return (<Marker key={counter++} lat={result.venue.lat} lng={result.venue.lon}
sport={this.props.sport} data={result}/>);
})}
</GoogleMap>
Upvotes: 15
Views: 35120
Reputation: 7484
You are mixing up props and state in the component. sports should only be in props, it shouldn't be in state as it is being passed in from the parent component.
constructor(props) {
(props);
this.state = {
events: [{venue: {lat: 2, lon: 1}}] <== removed sports here, it didn't belong
};
componentWillReceiveProps (nextProps) {
this.setState({events: [{venue: {lat: 2, lon: 1}}],
sports: nextProps.sports});
console.log(nextProps.sports);
}
static defaultProps = {
center: {lat: 36.160338, lng: -86.778780},
zoom: 12,
sports: ["baseball", "football", "paddle", "soccer", "boxing", "dart", "biking", "golf", "hockey", "inline-skating", "tennis", "volleyball", "skateboard", "kickball", "bowling", "pool", "ride", "hike", "ice-skating"],
};
makeMapEvents (insertProps) {
fetch("./json/meetup.json").then((response) => {
return response.json()
}).then((response) => {
/* eventually returns new events object based on insertProps */
this.setState({events: response});
}
};
componentDidMount () {
this.makeMapEvents(this.props.sports); <== changed to props.sports
console.log("mounted", this.props.sports); <== changed to props.sports
}
Upvotes: 1
Reputation: 5597
React ES6 classes do not autobind this
by default to non-react base member methods. Therefore, the context for this
in your function makeMapEvents
is not bound correctly. There are 2 ways to fix this:
Via ES7 property initializer:
makeMapEvents = (insertProps) => {
fetch("./json/meetup.json").then((response) => {
return response.json()
}).then((response) => {
/* eventually returns new events object based on insertProps */
this.setState({events: response});
})
};
Via binding in constructor:
constructor(props) {
(props);
this.state = {
events: [{venue: {lat: 2, lon: 1}}],
sports: ["baseball", "football", "paddle", "soccer", "boxing", "dart", "biking", "golf", "hockey", "inline-skating", "tennis", "volleyball", "skateboard", "kickball", "bowling", "pool", "ride", "hike", "ice-skating"]
};
this.makeMapEvents = this.makeMapEvents.bind(this) // << important line
}
Upvotes: 6
Reputation: 16650
The probable cause is that your makeMapEvents()
function doesn't provide the correct lexical value of this
when calling this.setState()
and as a result your code doesn't work. Change the makeMapEvents()
function definition to use Arrow function (() => {}
) and provide correct lexically bound value of this as:
makeMapEvents = (insertProps) => {
fetch("./json/meetup.json").then((response) => {
return response.json()
}).then((response) => {
this.setState({events: response});
}); // <-- Typo here. The closing parenthesis is missing
};
Also there is a typo in your code wherein the closing parenthesis is missing as shown in comments above
Upvotes: 1
Reputation: 4154
.then((response) => {
this.setState({events: resp});
}
You take in parameter response
then try to use resp
which isnt the variable you want.
Upvotes: 3