0

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

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

1 Comment

Your comment on my answer is correct. Thank you for pointing this out. I must have read the post too quickly. I'm withdrawing my answer. 👍🙏

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.