javascript - 从子组件中状态的数组中删除项目
问题描述
尝试使用单击处理程序从我所在州的餐食数组中删除一个项目,但它没有按预期工作。我已经看到了将第二个参数传递给 .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)}>
×
</button>
</li>
);
}
}
解决方案
你正在传递关于你的方法name
的饭菜。因为will be ,您将始终使用 删除数组的最后一个元素。e
removeMeal
e.target
undefined
splice(-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)}
>
×
</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>
推荐阅读
- terraform - 你如何为 IAC 设置你的仓库?
- node.js - 我必须为迁移回滚编写反向操作吗?
- php - 如何通过 php 使用 sendgrid 正确发送电子邮件
- c# - C# Windows 窗体应用程序 ListView:如何强制 ListView 不更新?
- php - 无法将值添加到关联数组 php
- azure-devops - 当我包含代码覆盖率时,无法获得 Azure DevOps Release Pipelines
- c - 在 gcc 中编译 c 时收到有关强制转换“从指针到不同大小的整数”的警告
- java - 无效标志:将 java 包升级到 1.8.0_211 后的 -jar
- python - 如何在 Subprocess.run 命令中使用 for 循环
- python-3.x - 如何让我的计算机识别用 python3 编写的代码?