首页 > 解决方案 > 从子组件中状态的数组中删除项目

问题描述

尝试使用单击处理程序从我所在州的餐食数组中删除一个项目,但它没有按预期工作。我已经看到了将第二个参数传递给 .map 函数的其他示例,但我在 Meal.js 中没有 .map。我可能可以通过将 Meal.js HTML 移动到 MealList.js 来修复它,但我想通过将它们分开来保持代码更简洁。

我缺少什么来实现这一点?现在,当我单击 X 按钮删除该项目时,它会删除除一个项目之外的所有项目。

应用程序.js:

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            meals: []
        };
        this.removeMeal = this.removeMeal.bind(this);
    }


    componentDidMount() {
        const meals = [
            {
                id: 1,
                name: "Test one",
                ingredients: [
                    "stuff 1",
                    "stuff 2"
                ]
            },
            {
                id: 2,
                name: "Test two",
                ingredients: [
                    "stuff 1",
                    "stuff 2"
                ]
            },
        ];

        this.setState({
            meals: meals
        });
    }

    removeMeal(e) {
        const meals = this.state.meals;
        const index = meals.indexOf(e.target);
        const newMeals = meals.splice(index, 1);
        this.setState({
            meals: newMeals
        });
    }

    render() {
        return (
            <section>
                <Router>
                    <MealList
                        path="/"
                        meals={this.state.meals}
                        removeMeal={this.removeMeal}
                    />
                </Router>
            </section>
        );
    }

MealList.js:

class MealList extends Component {
    render() {
        return (
            <div>
                <ul className="meal-list">
                    {this.props.meals.map((meal, i) => {
                        return (
                            <Meal
                                name={meal.name}
                                ingredients={meal.ingredients}
                                key={meal.id}
                                removeMeal={this.props.removeMeal}
                            />
                        );
                    })}
                </ul>
            </div>
        );
    }
}

Meal.js:

class Meal extends Component {

    render() {
        return (
            <li>
                <h2>{this.props.name}</h2>
                <ul className="ingredient-list">
                    {this.props.ingredients.map(item => {
                        return <li key={item}>{item}</li>;
                    })}
                </ul>

                <button type="button" className="remove-recipe" onClick={() => this.props.removeMeal(this.props.name)}>
                    &times;
                </button>
            </li>
        );
    }
}

标签: javascriptreactjs

解决方案


你正在传递关于你的方法name的饭菜。因为will be ,您将始终使用 删除数组的最后一个元素。eremoveMeale.targetundefinedsplice(-1, 1)

您可以改为使用数组方法filter来过滤掉name传递给removeMeal方法的对象。

removeMeal = name => {
  this.setState(prevState => {
    const meals = prevState.meals.filter(meal => meal.name !== name);
    return { meals };
  });
};

class App extends React.Component {
  state = {
    meals: [
      {
        id: 1,
        name: "Test one",
        ingredients: ["stuff 1", "stuff 2"]
      },
      {
        id: 2,
        name: "Test two",
        ingredients: ["stuff 1", "stuff 2"]
      }
    ]
  };

  removeMeal = name => {
    this.setState(prevState => {
      const meals = prevState.meals.filter(meal => meal.name !== name);
      return { meals };
    });
  };

  render() {
    return (
      <section>
        <MealList
          path="/"
          meals={this.state.meals}
          removeMeal={this.removeMeal}
        />
      </section>
    );
  }
}

class MealList extends React.Component {
  render() {
    return (
      <div>
        <ul className="meal-list">
          {this.props.meals.map((meal, i) => {
            return (
              <Meal
                name={meal.name}
                ingredients={meal.ingredients}
                key={meal.id}
                removeMeal={this.props.removeMeal}
              />
            );
          })}
        </ul>
      </div>
    );
  }
}

class Meal extends React.Component {
  render() {
    return (
      <li>
        <h2>{this.props.name}</h2>
        <ul className="ingredient-list">
          {this.props.ingredients.map(item => {
            return <li key={item}>{item}</li>;
          })}
        </ul>

        <button
          type="button"
          className="remove-recipe"
          onClick={() => this.props.removeMeal(this.props.name)}
        >
          &times;
        </button>
      </li>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>


推荐阅读