我对React相对较新,并创建了一个ToDoList风格的Recipe App。用户应该能够将新配方添加到列表中,以及删除或编辑现有配方。
我遇到了一个问题,让成分显示在不同的线条和asked this question如何做到这一点。最终结果是我在容器中添加了第二个.map
函数来迭代成分并将每个函数显示为新的段落元素。这是我的容器,Item.js
:
import React from 'react';
import Button from 'react-bootstrap/lib/Button';
const Item = (props) => (
<div>
<div className="Recipe-Item-Container" key={props.text}>
{/* Iterates through recipe item names and displays them */}
{props.items.map((item, index) => {
return (
<div className="Recipe-Item" key={index}>
<h3>{item}</h3>
// This is what I added
{/* Iterates through recipe ingriedients and displays them*/}
<p className="ingredients-list">
{props.ingredients[index].map((ingredient, ingredientIndex) => {
return (
<div className="ingredient" key={ingredient}>
{ingredient}
</div>
)
})}
</p>
<div className="buttons-container">
<Button className="edit-button" onClick={() => props.edit(item, index)}>Edit</Button>
<Button className="delete-button" onClick={() => props.delete(item, index)}>Delete</Button>
</div>
</div>
);
}
)}
</div>
</div>
)
export default Item;
现在,我所在州的初始食谱正确显示新行上的成分,用户编辑的任何食谱项目也会在新行上显示成分。正是我想要的。
问题是当用户添加新配方时,成分不会按照我想要的方式显示在新行上。如果单击添加新配方按钮并添加新配方,则成分将并排显示,并作为单个段落元素显示。
我有两个函数可以处理添加新配方和编辑现有配方onSubmit
和onEditSubmit
。 onEditSubmit
工作正常,因为在编辑食谱时,成分会在不同的行上正确显示。 onSubmit
是问题。我如何更改onSubmit
并让它在新线上显示成分并作为单独的段落?我认为这是我在onSubmit
中设置状态的问题,可能涉及使用扩展运算符。
这是我的App.js
:
import React, { Component } from 'react';
import Item from './Item';
import './App.css';
import ModalComponent from './Modal.js';
import Button from 'react-bootstrap/lib/Button';
import EditModalComponent from './EditModal.js';
import SimpleStorage from "react-simple-storage";
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,
// Index to select which recipe item is being edited
editingIndex: ''
};
}
// 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
});
}
// When user edits existing recipe this adds it to the list
onEditSubmit = (event) => {
event.preventDefault();
const {items, ingredients, inputValEdit, ingredientValEdit, editingIndex} = this.state;
// Selects proper recipe item to edit
items[editingIndex] = inputValEdit;
ingredients[editingIndex] = ingredientValEdit.split(',');
this.setState({
items: items,
ingredients: ingredients,
inputVal: '',
ingredientVal: '',
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) => {
this.setState({
showRecipeEditForm: !this.state.showRecipeEditForm,
editingIndex: index
});
}
// 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="container">
{/* Handles storing data in local sessions via react-simple-storage*/}
<SimpleStorage parent={this} />
<h1>Recipe List</h1>
<ModalComponent
inputVal={this.state.inputVal}
handleChange={this.handleChange}
ingredientVal={this.state.ingredientVal}
onSubmit={this.onSubmit}
addRecipe={this.addRecipe}
showRecipeForm={this.state.showRecipeForm}
closeRecipeForm={this.closeRecipeForm}
/>
<EditModalComponent
inputValEdit={this.state.inputValEdit}
handleChange={this.handleChange}
ingredientValEdit={this.state.ingredientValEdit}
onEditSubmit={this.onEditSubmit}
closeRecipeForm={this.closeRecipeForm}
addRecipe={this.addRecipe}
showRecipeEditForm={this.state.showRecipeEditForm}
/>
<Item
items={this.state.items}
ingredients={this.state.ingredients}
edit={this.edit}
delete={this.delete}
/>
<Button className="add-recipe-button" onClick={this.AddRecipe}>Add New Recipe</Button>
</div>
);
}
}
我需要让onSubmit
更像onEditSubmit
吗?如果是这样我怎么能这样做?
在您的商店中,您的成分变量是一个数组array.[ [a, b] , [c, d]]
您需要像在onEditSubmit中那样遵循此格式。 .split()
函数返回一个数组并将其保存到状态。
更改onSubmit中的部分
this.setState({
items: [...this.state.items, this.state.inputVal],
ingredients: [...this.state.ingredients, [this.state.ingredientVal]],
showRecipeForm: false
});
至
this.setState({
items: [...this.state.items, this.state.inputVal],
ingredients: [...this.state.ingredients, this.state.ingredientVal.split(',')],
showRecipeForm: false
});