更新状态多个下拉菜单

问题描述 投票:0回答:1

我有一个按钮,它可以根据我的状态中设置的数组项目数量添加一个下拉选择。

我可以添加一个新的下拉菜单,但是我很难更新每个下拉菜单的状态值。每次我选择下拉菜单并更改选项时,状态都会恢复到只有1个项目在数组中。

任何想法,我如何能够设置状态与他们的当前值为每个下拉,我有?

代码和框的例子

    state = {
            food: [
               {name: 'Apple', quantity: 1}
            ],
        };

    const addFood = this.state.food.map((item, idx) => {

    return 
         <Dropdown type="food"
              className="dropdown-food"
              label='food'
              key={idx}
              value={this.state.food[idx].name}
              change={(event) => this.setState({ food: [{ name: event.target.value, quantity: this.state.food[idx].quantity }] })}
         />

    })

    <Button styleName="add" label="Add Food" clicked={this.addAdditionalFood}/>
javascript reactjs state setstate
1个回答
1
投票

我解决了你的问题。现在代码的工作原理和预期的一样:1.当点击按钮时,在状态中添加一个新的下拉菜单和一个新的元素2.当下拉菜单的值发生变化时,它的状态也相应地发生变化。

为了解决这个问题,我只修改了App.js文件中的代码。这里是完整的代码。

import React, { Component } from "react";
import Dropdown from "./Dropdown";
import Button from "./Button";

class App extends Component {
  state = {
    food: [{
        name: "Apple",
        quantity: 1
      }]
  };

  addAdditionalFood = () => {
    const newState = {...this.state, 
      food : [...this.state.food,{
       name: "Apple",
       quantity: 1
      } ]};
    this.setState(newState);
  };

  selectFood = (event, index) => {
    const newState = {...this.state, 
      food : [
          ...this.state.food.slice(0, index),
          {
            ...this.state.food[index],
            name: event.target.value,
          },
          ...this.state.food.slice(index + 1)
            ]};
    this.setState(newState);
  }


  render() {
    const addFood = this.state.food.map((item, idx) => {
      return (
        <Dropdown
          type="food"
          label="food"
          key={idx}
          value={this.state.food[idx].name}
          change={(event) => this.selectFood(event, idx)}
        />
      );
    });

    return (
      <div className="App">
        {addFood}
        <Button label="Add Food" clicked={this.addAdditionalFood} />
      </div>
    );
  }
}

export default App;

这里是为一个新的下拉菜单添加一个额外状态的代码。

 addAdditionalFood = () => {
    const newState = {...this.state, 
      food : [...this.state.food,{
       name: "Apple",
       quantity: 1
      } ]};
    this.setState(newState);
  };

为了保证状态的不变性,好的做法是不直接对状态进行修改,而是对浅层副本的数据进行操作。在这段代码中,我告诉做一个状态的浅层副本,一个食物的浅层副本,最后,给食物浅层副本添加一个新的值。最后,我设置了新的状态。

这里是改变下拉菜单状态的代码。

selectFood = (event, index) => {
    const newState = {...this.state, 
      food : [
          ...this.state.food.slice(0, index),
          {
            ...this.state.food[index],
            name: event.target.value,
          },
          ...this.state.food.slice(index + 1)
            ]};
    this.setState(newState);
  }

这个函数把事件和下拉菜单的索引作为输入;事件中包含了下拉菜单所承担的新值--这个值必须在状态中输入。在这段代码中,我告诉要做一个状态的浅层副本,一个重新排列的食物浅层副本。这个浅层副本是这样构成的:在索引位置前后等于原始的,在索引位置不同。索引位置的元素是原件的浅层副本,但它与原件的区别在于名称。最后,我设置了新的状态。

这里是渲染下拉的代码。

<Dropdown
          type="food"
          label="food"
          key={idx}
          value={this.state.food[idx].name}
          change={(event) => this.selectFood(event, idx)}
        />

现在它不包含逻辑,只有一个lambda. 不要在jsx里面定义逻辑,而是在类级使用lambda。

如果改变水果的数量,我建议把下拉和输入框包在一起,然后传递给这个新组件两个函数:selectFood和selectQuantity。

注:我为我之前的答案和他们的bug道歉。现在,代码工作了,并且正确应用了不可变性。

© www.soinside.com 2019 - 2024. All rights reserved.