React - 根据用户在单击按钮后输入的文本更新 class 组件中的状态
React - Update state in class component based on text inputted by user after button click
我对 React 和创建待办事项列表样式 Recipe 应用比较陌生。用户应该能够添加新食谱、删除现有食谱或编辑现有食谱。我在编写允许用户单击编辑按钮然后向该食谱项提交新食谱标题 and/or 新成分的函数时遇到问题。
Here is the project。单击其中一个编辑按钮并提交表单后,如何更新该食谱项的食谱 title/ingredients 以显示用户提交的内容?我的 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;
很确定我正在犯一个 noob 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;
您需要扩展 <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
});
}
希望对您有所帮助!
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}
我对 React 和创建待办事项列表样式 Recipe 应用比较陌生。用户应该能够添加新食谱、删除现有食谱或编辑现有食谱。我在编写允许用户单击编辑按钮然后向该食谱项提交新食谱标题 and/or 新成分的函数时遇到问题。
Here is the project。单击其中一个编辑按钮并提交表单后,如何更新该食谱项的食谱 title/ingredients 以显示用户提交的内容?我的 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;
很确定我正在犯一个 noob 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;
您需要扩展 <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
});
}
希望对您有所帮助!
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}