我是React的新手,并创建了一个待办事项列表风格的食谱应用程序。用户应该能够添加新配方,删除现有配方或编辑现有配方。我在编写允许用户单击编辑按钮然后向该配方项目提交新配方标题和/或新配料的功能时遇到问题。
Here is the project。如何在单击其中一个编辑按钮并提交表单后更新该配方项目的配方标题/成分以显示用户提交的内容?我在我的App.js文件中有一个名为onSubmit
的函数,它处理用户创建的新配方项并将它们添加到列表中。我现在正在尝试实现一个名为onEditSubmit
的类似函数,它允许用户更新现有的食谱项目,但我被卡住了。
这是我所在州的App.js:
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
items: ["Pumpkin Pie", "Spaghetti", "Onion Pie"],
ingredients:[
["Pumpkin Puree ", "Sweetened Condensed Milk ", "Eggs ", "Pumpkin Pie Spice ", "Pie Crust "],
["Noodles ", "Tomato Sauce ", "(Optional) Meatballs "],
["Onion ", "Pie Crust "]
],
// Recipe name and ingredients
inputVal: '',
ingredientVal: '',
// Recipe name and ingredients when user is editing existing recipe
inputValEdit: '',
ingredientValEdit: '',
// Controls whether forms are displayed or hidden
showRecipeForm: false,
showRecipeEditForm: false
};
}
// Get text user inputs for recipes
handleChange = (event) => {
this.setState({ [event.target.name]: event.target.value });
};
// When user submits recipe this adds it to the list
onSubmit = (event) => {
event.preventDefault()
this.setState({
items: [...this.state.items, this.state.inputVal],
ingredients: [...this.state.ingredients, this.state.ingredientVal],
showRecipeForm: false
});
}
// Should edit and update a recipe item when user clicks edit button and then submits RecipeEditForm, not working
onEditSubmit = (event) => {
event.preventDefault()
// This setState shoul erase previous recipe state and rewrite it with the details the user entered after editing that particular recipe item
this.setState({
items: this.state.inputValEdit,
ingredients: this.state.ingredientValEdit,
showRecipeEditForm: false
});
}
closeRecipeForm = () => {
this.setState({
showRecipeForm: false,
showRecipeEditForm: false
});
}
// Shows recipe
AddRecipe = (bool) => {
this.setState({
showRecipeForm: bool
});
}
// Is called when one of the edit recipe buttons is clicked, shows RecipeEditForm
edit = (item, index) => {
console.log('Edit button clicked');
console.log('index is ' + index);
this.setState({ showRecipeEditForm: !this.state.showRecipeEditForm });
}
// Deletes recipe item from the list
delete = (item, index) => {
this.setState({
ingredients : this.state.ingredients.filter((_, i) => i !== index),
items: this.state.items.filter((_, i) => i !== index)
});
}
render() {
return (
<div className="Recipe-List">
<h1>Recipe List</h1>
<Item
items={this.state.items}
ingredients={this.state.ingredients}
edit={this.edit}
delete={this.delete}
/>
<button onClick={this.AddRecipe}>Add New Recipe</button>
{/* Shows form to edit recipe */}
{ this.state.showRecipeEditForm ?
<RecipeEditForm
inputValEdit={this.state.inputValEdit}
handleChange={this.handleChange}
ingredientValEdit={this.state.ingredientValEdit}
onEditSubmit={this.onEditSubmit}
closeRecipeForm={this.closeRecipeForm}
/>
:null
}
{/* Shows form to add new recipe to the list */}
{ this.state.showRecipeForm ?
<RecipeForm
inputVal={this.state.inputVal}
handleChange={this.handleChange}
ingredientVal={this.state.ingredientVal}
onSubmit={this.onSubmit}
closeRecipeForm={this.closeRecipeForm}
/>
:null
}
</div>
);
}
}
这是我的Item.js函数容器的数据。当onSubmit
使用它来添加新配方时,此容器工作正常。但是当onEditSubmit
试图使用它时,我得到一个错误,props.items.map is not a function
。
import React from 'react';
const Item = (props) => (
<div>
<div className="Recipe-Item" key={props.text}>
{props.items.map((item, index) =>
<div className="Recipe-Item-Container">
<ul>
<li key={index}>
{item}
</li>
<li>
{props.ingredients[index]}
</li>
</ul>
<button onClick={() => props.edit(item, index)}>Edit</button>
<button onClick={() => props.delete(item, index)}>Delete</button>
</div>
)}
</div>
</div>
)
export default Item;
很确定我正在制作菜鸟React错误,但我不确定问题是什么。
编辑纠正onSubmitError函数中的语法错误:inputVal更改为inputValEdit,ingredientVal更改为ingredientValEdit
以下是onSubmit
的功能组件:
import React, { Component } from 'react';
const RecipeForm = (props) => {
return (
<div>
<form className="Recipe-Form" onSubmit={props.onSubmit}>
<p className="x-close" onClick={props.closeRecipeForm}>X</p>
<div className="form-content">
<label>Recipe Name</label>
<input
name="inputVal"
value={props.inputVal}
onChange={props.handleChange}
/>
<label>Ingredients</label>
<input
name="ingredientVal"
value={props.ingredientVal}
onChange={props.handleChange}
/>
<button>Submit</button>
</div>
</form>
</div>
);
}
export default RecipeForm;
这是onEditSubmit
的功能组件:
import React, { Component } from 'react';
const RecipeEditForm = (props) => {
return (
<div>
<form className="Recipe-Form Edit-Form" onSubmit={props.onEditSubmit}>
<p className="x-close" onClick={props.closeRecipeForm}>X</p>
<div className="form-content">
<h1>This is the edit form</h1>
<label>Edit Recipe</label>
<input
name="inputValEdit"
value={props.inputValEdit}
onChange={props.handleChange}
/>
<label>Ingredients</label>
<input
name="ingredientValEdit"
value={props.ingredientValEdit}
onChange={props.handleChange}
/>
<button>Submit</button>
</div>
</form>
</div>
);
}
export default RecipeEditForm;
onEditSubmit = (event) => {
event.preventDefault()
// This setState shoul erase previous recipe state and rewrite it with the
details the user entered after editing that particular recipe item
this.setState({
items: this.state.inputVal,
ingredients: this.state.ingredientVal,
showRecipeEditForm: false
});
}
你将items
状态字段设置为字符串。您应该将其更改为:
onEditSubmit = (e) => {
e.preventDefault();
const {items, ingredients, inputVal, ingredientVal, editingIndex} = this.state;
items[editingIndex] = inputVal;
ingredients[editingIndex] = ingredientVal;
this.setState({
items,
ingredients,
inputVal: '',
ingredientVal: ''
});
}
你可以在editingIndex
函数中存储edit
:setState({editingIndex: index}
您需要扩展<App/>
状态,以便您的应用程序可以跟踪当前正在编辑的食谱列表中的哪个食谱项目。
例如,您可以存储用户正在编辑的配方数据的索引。然后,您将使用此索引在onEditSubmit()
函数期间更新列表中的正确配方:
onEditSubmit = (event) => {
event.preventDefault()
// Get the index of the recipe we're currently editing
const currentlyEditingIndex = this.state.currentlyEditingIndex
// Clone data arrays for mutation
const items = [].concat(this.state.items)
const ingredients = [].concat(this.state.ingredients)
// Update data arrays
items[ currentlyEditingIndex ] = this.state.inputValEdit;
ingredients[ currentlyEditingIndex ] = this.state.ingredientValEdit;
this.setState({
items: items,
ingredients: ingredients,
showRecipeEditForm: false
});
}
为此,您还需要更新edit
函数,如下所示:
edit = (item, index) => {
console.log('Edit button clicked');
console.log('index is ' + index);
this.setState({
// Store the index of the recipe being edited
currentlyEditingIndex : index,
showRecipeEditForm: !this.state.showRecipeEditForm
});
}
希望这可以帮助!