首页 > 解决方案 > 在 React 中将单击的项目添加到新数组

问题描述

我正在进行 API 调用并在对象中呈现不同的组件。其中之一如下所示:

class Bases extends Component {
    constructor() {
        super();

        this.state = {
            'basesObject': {}
        }
    }

    componentDidMount() {
        this.getBases();
    }

    getBases() {
        fetch('http://localhost:4000/cupcakes/bases')
        .then(results => results.json())
        .then(results => this.setState({'basesObject': results}))
    }

    render() {

        let {basesObject} = this.state;  
        let {bases} = basesObject; 

        console.log(bases); 
        //FALSY values: undefined, null, NaN, 0, false, ""

        return (

            <div>
                {bases && bases.map(item =>
                    <button key={item.key} className="boxes">
                        {/* <p>{item.key}</p> */}
                        <p>{item.name}</p>
                        <p>${item.price}.00</p>
                        {/* <p>{item.ingredients}</p> */}
                    </button>
            )}
           </div>
        )
    }
}

上面呈现了一组按钮。我所有的组件看起来基本相同。

我在这里渲染我的组件:

class App extends Component {
  state = {
    ordersArray: []
  }

  render() {
    return (
      <div>
        <h1>Bases</h1>
        <Bases />
        <h1>Frostings</h1>
        <Frostings />
        <h1>Toppings</h1>
        <Toppings />
      </div>
    );
  }
}

我需要找出最简单的方法,当用户单击按钮时,将每个单击元素的键添加到新数组中,但我不确定从哪里开始。用户必须选择其中一种,但可以选择任意数量的浇头。

标签: javascriptreactjs

解决方案


在此处输入图像描述

尝试这个

我们可以对所有类别使用相同的组件。所有数据都由父级(无状态组件)处理。

function Buttons({ list, handleClick }) {
  return (
    <div>
      {list.map(({ key, name, price, isSelected }) => (
        <button
          className={isSelected ? "active" : ""}
          key={key}
          onClick={() => handleClick(key)}
        >
          <span>{name}</span>
          <span>${price}</span>
        </button>
      ))}
    </div>
  );
}

在组件中获取数据App,将数据和 handleClick 方法传递到Buttons.

class App extends Component {
  state = {
    basesArray: [],
    toppingsArray: []
  };

  componentDidMount() {
    // Get bases and toppings list, and add isSelected attribute with default value false
    this.setState({
      basesArray: [
        { key: "bases1", name: "bases1", price: 1, isSelected: false },
        { key: "bases2", name: "bases2", price: 2, isSelected: false },
        { key: "bases3", name: "bases3", price: 3, isSelected: false }
      ],
      toppingsArray: [
        { key: "topping1", name: "topping1", price: 1, isSelected: false },
        { key: "topping2", name: "topping2", price: 2, isSelected: false },
        { key: "topping3", name: "topping3", price: 3, isSelected: false }
      ]
    });
  }

  // for single selected category
  handleSingleSelected = type => key => {
    this.setState(state => ({
      [type]: state[type].map(item => ({
        ...item,
        isSelected: item.key === key
      }))
    }));
  };

  // for multiple selected category
  handleMultiSelected = type => key => {
    this.setState(state => ({
      [type]: state[type].map(item => {
        if (item.key === key) {
          return {
            ...item,
            isSelected: !item.isSelected
          };
        }
        return item;
      })
    }));
  };

  // get final selected item
  handleSubmit = () => {
    const { basesArray, toppingsArray } = this.state;
    const selectedBases = basesArray.filter(({ isSelected }) => isSelected);
    const selectedToppings = toppingsArray.filter(({ isSelected }) => isSelected);

    // submit the result here
  }

  render() {
    const { basesArray, toppingsArray } = this.state;

    return (
      <div>
        <h1>Bases</h1>
        <Buttons
          list={basesArray}
          handleClick={this.handleSingleSelected("basesArray")}
        />
        <h1>Toppings</h1>
        <Buttons
          list={toppingsArray}
          handleClick={this.handleMultiSelected("toppingsArray")}
        />
      </div>
    );
  }
}

export default App;

CSS

button {
  margin: 5px;
}
button.active {
  background: lightblue;
}

推荐阅读