I'm trying to map over an array of a fetched API to separate the individual items with the same name, and setState based on that individual item property. For instance, the array returns multiple different items with different latitudes and longitudes. I am able to setState using a function in the onClick inside the render function, however I know this is bad practice. I've tried moving the function outside of render and using onClick={this.functionName}, but this gives weird behavior. What am I doing wrong?
here is the function I created outside of the render:
mapItem = () => {
const parks = [...this.state.parks];
parks.map(item =>
this.setState({
lat: item.latitude,
lng: item.longitude,
zoom: 16
})
);
};
render() {
return (<h2 onClick={this.mapItem}>{item.name}</h2>)
}
this works:
render() {
const { parks } = this.state;
return(
{parks.map(item => (
<h2 onClick={() => this.setState({lat: item.latitude,
lng: item.longitude, zoom: 16})
}>{item.name}</h2>
))
)}}
thank you
This is how you can move the onClick event handler outside of render()
:
handleClick = item => {
this.setState({
lat: item.latitude,
lng: item.longitude,
zoom: 16
})
}
render() {
const { parks } = this.state
return (
<>
{parks.map(item => (
<h2
onClick={() => {
this.handleClick(item)
}}
>
{item.name}
</h2>
))}
</>
)
}
If you are trying to avoid any inline-functions in render()
(because each render will create a new instance of that function), then you will have to create a separate component for each parks
's item:
// ParkItem functional component
const ParkItem = ({item}) => {
const handleClick = () => {
this.props.setCoordinate({
lat: item.latitude,
lng: item.longitude,
zoom: 16
})
}
return <h2 onClick={handleClick}>{item.name}</h2>
}
class YourCurrentClass extends Component {
setCoordinate = stateObj => {
this.setState(stateObj)
}
render() {
const { parks } = this.state
return (
<>
{parks.map(item => (
<ParkItem item={item} />
))}
</>
)
}
}
export default YourCurrentClass