Событие onCLick для элемента сопоставленного массива

Суть в том, чтобы получить кликабельные HTML-теги, сделанные из сопоставленного массива и только кликнувшего элемента, вызванного событием onClick:

class Elements extends Component {
        constructor(props) {
            super(props);
            this.state = {
                backgroundColor: 'pink'
            }
        }
        click = (e, i) => {
            this.setState({
                backgroundColor: 'blue'
            });
        }
        render() {
            let buttons = ['one','two','three','four'];
            return (
                <div>
                    {
                        buttons.map( (e, index) => {
                            return (
                                <button key={index}
                                        style={this.state.style}
                                        onClick={this.click}> {e} </button> 
                                              // e => this.click(e, i)?
                            );
                        } )
                    }
                </div>
            )
        }
    }

это, вероятно, можно решить с помощью e.currentTarget.style.... или с помощью метода onClick с передачей индивидуальной опции (здесь 'i'), но я не понимаю логику этих методов и не знаю, как их применять правильно. Кто-нибудь?

1 ответ

Решение

Вы можете сохранить объект в вашем состоянии с именем, например, backgroundColors который содержит пары ключ / значение, представляющие кнопку и ее цвет фона. Если у кнопки нет ключа в этом объекте, вы можете вернуться к pink,

Вы можете использовать новую встроенную функцию стрелки для отправки имени кнопки в обработчик событий, как вы указали в своем комментарии.

пример

class Elements extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      buttons: ["one", "two", "three", "four"],
      backgroundColors: {}
    };
  }

  click = button => {
    this.setState(prevState => ({
      backgroundColors: {
        ...prevState.backgroundColors,
        [button]: "blue"
      }
    }));
  };

  render() {
    const { buttons, backgroundColors } = this.state;

    return (
      <div>
        {buttons.map(button => {
          return (
            <button
              key={button}
              style={{ backgroundColor: backgroundColors[button] || "pink" }}
              onClick={() => this.click(button)}
            >
              {button}
            </button>
          );
        })}
      </div>
    );
  }
}

ReactDOM.render(<Elements />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Вы также можете использовать data-* свойство, если вы абсолютно не хотите использовать новую встроенную функцию в методе рендеринга.

пример

class Elements extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      buttons: ["one", "two", "three", "four"],
      backgroundColors: {}
    };
  }

  click = event => {
    const { button } = event.target.dataset;
    this.setState(prevState => ({
      backgroundColors: {
        ...prevState.backgroundColors,
        [button]: "blue"
      }
    }));
  };

  render() {
    const { buttons, backgroundColors } = this.state;

    return (
      <div>
        {buttons.map(button => {
          return (
            <button
              key={button}
              style={{ backgroundColor: backgroundColors[button] || "pink" }}
              data-button={button}
              onClick={this.click}
            >
              {button}
            </button>
          );
        })}
      </div>
    );
  }
}

ReactDOM.render(<Elements />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Другие вопросы по тегам