bronzehedwick
bronzehedwick

Reputation: 3013

How do I set state for dynamically generated items in React?

I am fetching some data from the server to populate a list of items, and I want to change the class of the item that's clicked. However, since state is singular for each component, it updates the class on every item. How to I limit it only to the item clicked? Code below. Thanks.

let Item = React.createClass({
  getInitialState() {
    return { isItemOpen: false };
  },

  handleClick() {
   this.setState({ isItemOpen: !this.state.isItemOpen });
  },

  render() {
    let items = this.props.data.map((item) => {
      let itemClass = this.state.isItemOpen ? 'video-item open' : 'video-item';

      return (
          <article className={ itemClass } onClick={ this.handleClick }>
            <h1>{item.title}</h1>
            <p>{item.content}</p>
          </article>
      )
    });

    return (
      <div className="video-items">
        {videoItems}
      </div>
    )
  }
});

Upvotes: 1

Views: 2600

Answers (1)

Davin Tryon
Davin Tryon

Reputation: 67326

A better strategy might be to hold the id or title (some unique value) from the item that is clicked. Then hold the item id in state, instead of a boolean that cannot be differentiated during the loop. Something like this should work for you:

let Item = React.createClass({
  getInitialState() {
    return { itemOpened: -1 };
  },

  handleClick(id) {
   this.setState({ itemOpened: id });
  },

  render() {
    let items = this.props.data.map((item) => {
      let itemClass = (this.state.itemOpened === item.id) ? 'video-item open' : 'video-item';

      return (
          <article className={ itemClass } onClick={ this.handleClick.bind(this, item.id) }>
            <h1>{item.title}</h1>
            <p>{item.content}</p>
          </article>
      )
    });

    return (
      <div className="video-items">
        {items}
      </div>
    )
  }
});

Upvotes: 3

Related Questions