Реагирование / уменьшение изменения цвета фона кнопки во вложенном массиве с использованием состояния

#javascript #reactjs #redux

#javascript #reactjs #уменьшение

Вопрос:

Я уже целую вечность ломаю голову над этим.

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

У меня есть массив имен в парах, которые я перебираю дважды, используя карту, один раз, чтобы получить пару, и еще раз, чтобы получить значение. Я вывожу и присваиваю значения кнопке для каждого и отображаю пары вместе (например, каждая пара индексируется 0 и 1).

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

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

Любая помощь в этом была бы очень признательна, поскольку я, похоже, не могу найти способ обойти это. Спасибо!

 import React, { Component } from "react";
import "../../App.scss";
import { Link } from "react-router-dom";
import Button from "../Button/Button";

class Matches extends Component {
  constructor(props) {
    super(props);
    this.state = {
      champ: [],
      winningPlayers: [],
      selected: false,
    };
    this.handleAddWinners = this.handleAddWinners.bind(this);
    this.handleRound = this.handleRound.bind(this);
  }

  // Adds winners to a local array which is then sent
  // to the global array using the handleNextRound action.

  handleAddWinners = (e) => {
    const winner = e.target.value;
    const { champ } = this.state;
    const { round } = this.props;

    if (round !== 3) {
      this.setState({
        selected: !false,
        winningPlayers: [...this.state.winningPlayers, winner],
      });
    } else {
      this.setState({ champ: [...champ, winner] });
    }
  };

  handleRound = () => {
    const { round, handleNextRound, handleChampion } = this.props;

    round !== 3 ? handleNextRound(this.state) : handleChampion(this.state);

    this.setState({ winningPlayers: [] });
  };

  render() {
    const { pairs, round, handleClear, roundWinners, champion } = this.props;
    const { winningPlayers, selected, champ } = this.state;
    const semi = roundWinners[0];
    const final = roundWinners[1];
    const champName = champion.map((item) => item);
    const reset =
      round !== 4 ? "block__reset__tournament" : "block__reset__new-game";
    const newGame = `${round !== 4 ? "Reset" : "New Game?"}`;
    const buttonClick = `${selected ? "selected" : "block__player"}`;
   

    return (
      <>
        <div classname="container__wrapper">
          <div className="container__tournament">
            {round === 1 ? (
              <section className="block__round ">
                {pairs.map((item, index) => (
                  <div className="pairs" key={index}>
                    {item.map((names, index) => (
                      <Button
                        key={index}
                        handleClick={(e) => this.handleAddWinners(e)}
                        label={names}
                        buttonClass={buttonClick}
                        value={names}
                      />
                    ))}
                  </div>
                ))}
              </section>
            ) : round === 2 ? (
              <section className="block__round ">
                {semi.map((names, index) => (
                  <div className="pairs" key={index}>
                    {names.map((names, index) => (
                      <Button
                        key={index}
                        handleClick={(e) => this.handleAddWinners(e, "value")}
                        label={names}
                        buttonClass={buttonClick}
                        value={names}
                      />
                    ))}
                  </div>
                ))}
              </section>
            ) : round === 3 ? (
              <section className="block__round ">
                {final.map((names, index) => (
                  <div className="pairs" key={index}>
                    {names.map((names, index) => (
                      <Button
                        key={index}
                        handleClick={(e) => this.handleAddWinners(e, "value")}
                        label={names}
                        buttonClass={buttonClick}
                        value={names}
                      />
                    ))}
                  </div>
                ))}
              </section>
            ) : (
              <section className="block__champion">
                <p className="champion__greeting">
                  Congratulationsamp;nbsp;
                  <br />
                  <span className="champion__name">{champName}!</span>
                  <br /> You've won the whole shebang!
                </p>
              </section>
            )}

            <Button
              buttonClass={`${
                round !== 4 ? "block__next-round" : "button__notActive"
              }`}
              label={`${round !== 3 ? "Next Round" : "See Winner"}`}
              handleClick={this.handleRound}
              disabled={disabled}
            />

            <Link to={"/"} className={reset}>
              <Button
                buttonClass={reset}
                handleClick={handleClear}
                label={newGame}
              />
            </Link>
          </div>
        </div>
      </>
    );
  }
}

export default Matches;

  

Это компонент, который обрабатывает большую часть этого.

Комментарии:

1. вы присвоили обеим кнопкам событие ButtonClick, которое всегда устанавливало для «выбранного» значение true, и вы присвоили им один и тот же класс. Попробуйте присвоить выбранному значение по умолчанию null, отправьте handleAddWinners индекс пары и индекс ключа, а затем выполните сравнение с buttonClass, чтобы увидеть, совпадает ли индекс с выбранным…

2. Не могли бы вы показать пример? Извините, я изо всех сил пытаюсь это визуализировать.

Ответ №1:

Сначала я хотел бы сказать, что вам всегда следует избегать использования индекса массива в качестве ключей. То есть, если ваш массив не всегда одинакового размера и порядка. Сказав это, вы хотите узнать, какая кнопка была выбрана, верно? Итак, вам нужно сохранить последнюю выбранную кнопку. Поскольку вы нигде не используете никаких идентификаторов, вы можете использовать индекс пары и индекс кнопки, чтобы узнать, какая кнопка была нажата. Вот пример — я изменил только round1 и код состояния.

 import React, { Component } from "react";
import "../../App.scss";
import { Link } from "react-router-dom";
import Button from "../Button/Button";

class Matches extends Component {
  constructor(props) {
    super(props);
    this.state = {
      champ: [],
      winningPlayers: [],
      selected: null,
    };
    this.handleAddWinners = this.handleAddWinners.bind(this);
    this.handleRound = this.handleRound.bind(this);
  }

  // Adds winners to a local array which is then sent
  // to the global array using the handleNextRound action.

  handleAddWinners = (e, pairIndex, itemIndex) => {
    const winner = e.target.value;
    const { champ } = this.state;
    const { round } = this.props;

    if (round !== 3) {
      this.setState({
        selected: `${pairIndex}-${itemIndex}`,
        winningPlayers: [...this.state.winningPlayers, winner],
      });
    } else {
      this.setState({ champ: [...champ, winner] });
    }
  };

  handleRound = () => {
    const { round, handleNextRound, handleChampion } = this.props;

    round !== 3 ? handleNextRound(this.state) : handleChampion(this.state);

    this.setState({ winningPlayers: [] });
  };

  render() {
    const { pairs, round, handleClear, roundWinners, champion } = this.props;
    const { winningPlayers, selected, champ } = this.state;
    const semi = roundWinners[0];
    const final = roundWinners[1];
    const champName = champion.map((item) => item);
    const reset =
      round !== 4 ? "block__reset__tournament" : "block__reset__new-game";
    const newGame = `${round !== 4 ? "Reset" : "New Game?"}`;
    const buttonClick = `${selected ? "selected" : "block__player"}`;
   

    return (
      <>
        <div classname="container__wrapper">
          <div className="container__tournament">
            {round === 1 ? (
              <section className="block__round ">
                {pairs.map((item, pairIndex) => (
                  <div className="pairs" key={pairIndex}>
                    {item.map((names, itemIndex) => (
                      <Button
                        key={itemIndex}
                        handleClick={(e) => this.handleAddWinners(e, pairIndex, itemIndex)}
                        label={names}
                        buttonClass={`${pairIndex}-${itemIndex}` === selected ? '<enterYourBackgroundClass' : buttonClick}
                        value={names}
                      />
                    ))}
                  </div>
                ))}
              </section>
            ) : round === 2 ? (
              <section className="block__round ">
                {semi.map((names, index) => (
                  <div className="pairs" key={index}>
                    {names.map((names, index) => (
                      <Button
                        key={index}
                        handleClick={(e) => this.handleAddWinners(e, "value")}
                        label={names}
                        buttonClass={buttonClick}
                        value={names}
                      />
                    ))}
                  </div>
                ))}
              </section>
            ) : round === 3 ? (
              <section className="block__round ">
                {final.map((names, index) => (
                  <div className="pairs" key={index}>
                    {names.map((names, index) => (
                      <Button
                        key={index}
                        handleClick={(e) => this.handleAddWinners(e, "value")}
                        label={names}
                        buttonClass={buttonClick}
                        value={names}
                      />
                    ))}
                  </div>
                ))}
              </section>
            ) : (
              <section className="block__champion">
                <p className="champion__greeting">
                  Congratulationsamp;nbsp;
                  <br />
                  <span className="champion__name">{champName}!</span>
                  <br /> You've won the whole shebang!
                </p>
              </section>
            )}

            <Button
              buttonClass={`${
                round !== 4 ? "block__next-round" : "button__notActive"
              }`}
              label={`${round !== 3 ? "Next Round" : "See Winner"}`}
              handleClick={this.handleRound}
              disabled={disabled}
            />

            <Link to={"/"} className={reset}>
              <Button
                buttonClass={reset}
                handleClick={handleClear}
                label={newGame}
              />
            </Link>
          </div>
        </div>
      </>
    );
  }
}

export default Matches;

  

Комментарии:

1. Мой герой! большое вам спасибо. Что бы я сделал, чтобы сохранить выделение?

2. Вам нужно подумать об архитектуре того, чего вы пытаетесь достичь… Если вы хотите, вы можете открыть приватный чат, и мы можем поговорить там