简体   繁体   English

React/Redux 使用状态更改嵌套数组中按钮的背景颜色

[英]React/Redux Changing background colour of button in nested array using state

I've been scratching my head over this for ages now.多年来,我一直在为此挠头。

I am trying to change the background colour of a specific button that is in a nested array.我正在尝试更改嵌套数组中特定按钮的背景颜色。

I have an array of names in pairs that I loop over twice using a map, once to get the pair and once again to get the value.我有一个成对的名字数组,我使用地图循环了两次,一次是为了得到一对,再次是为了得到值。 I output and assign the values to a button for each and am displaying the pairs together (Eg each pair is indexed 0 and 1).我输出并将值分配给每个按钮,并将这些对显示在一起(例如,每对索引为 0 和 1)。

When I click on the button I wish to change only the background colour of the selected button.当我单击按钮时,我只想更改所选按钮的背景颜色。 Currently all the buttons change colour.目前所有按钮都会改变颜色。 The issue being is that the state of the buttons effects all of them when I use a boolean to define the selection.问题是当我使用布尔值来定义选择时,按钮的状态会影响所有按钮。

The handler I am using to do this also adds the value of the button to an array to be passed into global state later on as well.我用来执行此操作的处理程序还将按钮的值添加到稍后传递到全局状态的数组中。

Any help with this would be greatly greatly appreciated as I can't seem to find a way past it.对此的任何帮助将不胜感激,因为我似乎无法找到解决方法。 Thanks!谢谢!

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">
                  Congratulations&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;

This is the component that is handling most of this.这是处理大部分内容的组件。

First I would like to say that you should always avoid from using array's index as keys.首先,我想说您应该始终避免使用数组的索引作为键。 That is, unless your array is always at the same size and order.也就是说,除非您的数组始终具有相同的大小和顺序。 Having said that - what you want to do is to know which button was selected - right?话虽如此 - 您想要做的是知道选择了哪个按钮 - 对吗? So you need to store the last button that was selected.所以你需要存储最后一个被选中的按钮。 Because you don't use any ids anywhere, you can use the index of the pair and the index of the button to know which button was clicked.因为您没有在任何地方使用任何 id,所以您可以使用该对的索引和按钮的索引来知道点击了哪个按钮。 Here's an example - I've changed only the round1 and the state code.这是一个示例 - 我只更改了 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">
                  Congratulations&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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM