我有一个django / react(用于图像上传的s3存储桶)项目,该项目将配方添加到postgres数据库中。在我的RecipeFormContainer组件中,我对配方的属性之一是一组成分。该数组应该填充有由单位,数量等键值对组成的对象。我编写了一种名为addIngredients的方法,但似乎没有将这些对象添加到我的成分数组中。尝试提交我的食谱并发布信息时,出现错误“成分:[“此字段为必填。”]“。请用我所缺少的东西来启发我。 代码如下:
import React, {Component} from 'react';
import {Form} from 'react-bootstrap'
import Button from 'react-bootstrap/Button';
class RecipeFormContainer extends Component {
constructor(props) {
super(props);
this.state = {
title: '',
creator: '',
mealTime: "",
prepTime: "",
cookTime: "",
image_preview: "",
servings: "",
directions: '',
ingredients: [{
units: '',
amounts: '',
multiples: '',
quantity: '',
name: ''
}],
image: "",
};
this.handleImage = this.handleImage.bind(this);
this.handleIngredientInput = this.handleIngredientInput.bind(this);
this.handleAddIngredients = this.handleAddIngredients.bind(this);
}
handleAddIngredients =(e) => {
e.preventDefault();
// the ingredients properties are not being added to the ingredients array property on state *************************
let ingredient = {units: '',
amounts: '',
multiples: '',
quantity: '',
name: ''};
//save the current state of ingredients array in variable ingredient
let {ingredients} = this.state.ingredients;
// add the ingredient object into the ingredients array ( which is a property of state)
ingredients.push(ingredient);
// set the new array of ingredients as the state of the property ingredients
this.setState( {ingredients: ingredients});
};
handleInput = (e) => {
e.preventDefault();
this.setState({[e.target.name]: e.target.value});
};
handleIngredientInput = (e) => {
e.preventDefault();
this.setState({[e.target.name]: e.target.value})
};
handleImage(event) {
event.preventDefault();
// this makes it show up in preview
let file = event.target.files[0];
let fileReader = new FileReader();
fileReader.onloadend = () => this.setState({image_preview:fileReader.result});
fileReader.readAsDataURL(file);
this.setState({image:file});
}
submitRecipe = (event) => {
event.preventDefault();
let recipe = {...this.state};
console.log('recipe one', this.state);
let formData = new FormData();
formData.append("image", this.state.image);
formData.append('title', this.state.title);
formData.append("ingredients", this.state.ingredients);
formData.append("mealTime", this.state.mealTime);
formData.append("prepTime", this.state.prepTime);
formData.append("cookTime", this.state.cookTime);
formData.append("image_Preview", this.state.image_preview);
formData.append("servings", this.state.servings);
formData.append("directions", this.state.directions);
formData.append("creator", this.state.creator);
// formData.append("units", this.state.ingredients.units);
// formData.append("amount", this.state.ingredients.amount);
// formData.append("multiples", this.state.ingredients.multiples);
// formData.append("quantity", this.state.ingredients.quantity);
// formData.append("name", this.state.ingredients.name);
// add line for each property of state
const conf = {
method: "POST",
body: formData,
};
fetch('/api/recipe/', conf).then((response) => {
return response.json();
}).then((json) => {
this.props.addRecipe(json);
});
};
render() {
return (
<Form onSubmit={this.submitRecipe} encType="multipart/form-data" >
<Form.Group onSubmit={event => {event.preventDefault(); }} >
<img src={this.state.image_preview}/>
<input className="input" type="file" onChange={this.handleImage} name="image" />
</Form.Group>
<Form.Group controlId="exampleForm.ControlInput1">
<Form.Label>Recipe Name</Form.Label>
<Form.Control type="text" placeholder="Enter Recipe Name Here"
name="title"
value={this.state.title}
onChange={this.handleInput}/>
<Form.Label>Recipe Creator</Form.Label>
<Form.Control type="text" placeholder="Enter Your Name Here"
value={this.state.creator}
name="creator"
onChange={this.handleInput}/>
</Form.Group>
<Form.Group controlId="exampleForm.ControlSelect1" id="foodType">
<Form.Label>Example select</Form.Label>
<Form.Control as="select">
<option>Breakfast</option>
<option>Lunch</option>
<option>Dinner</option>
<option>Dessert</option>
<option>Vegetarian</option>
</Form.Control>
</Form.Group>
<Form.Control type="text" placeholder="Prep Time" className="midButt"
value={this.state.prepTime}
name="prepTime"
onChange={this.handleInput}/>
<Form.Control type="text" placeholder="Cook Time" className="midButt"
value={this.state.cookTime}
name="cookTime"
onChange={this.handleInput}/>
<Form.Group controlId="exampleForm.ControlSelect1" id="foodTemp">
<Form.Control as="select">
<option>Fahrenheit</option>
<option>Celsius</option>
</Form.Control>
</Form.Group>
<Form.Group>
This Recipe Will Make: <Form.Control type="number" placeholder="servings" id="servings" value={this.state.ingredients.servings} onChange={this.handleInput} name="servings" />
<Form.Control type="text" placeholder="cookies, loaves, etc." id="loaf" value={this.state.ingredients.multiples} onChange={this.handleIngredientInput} name="multiples"/>
</Form.Group>
{this.state.ingredients.map((ingredient, index) => {
return (
<div key={index}>
<Form.Control type="number" placeholder="#" id="numberAmount" value={this.state.ingredients.quantity} onChange={this.handleIngredientInput} name="amount"/>
<Form.Control type="text" placeholder="units" id="units" value={this.state.ingredients.units} onChange={this.handleIngredientInput} name="units"/>
<Form.Control type="text" placeholder="Ingredient Name" id="name" value={this.state.ingredients.name} onChange={this.handleIngredientInput} name="name"/>
</div>
);
})};
<Button variant="light" onClick = {this.handleAddIngredients}> + </Button>
{/*/!*will update state with event handler this.state.ingredients, append object to array *!/*/}
<Form.Group controlId="exampleForm.ControlTextarea1">
<Form.Label>Directions</Form.Label>
<Form.Control as="textarea" rows="3"
value={this.state.directions}
name="directions"
onChange={this.handleInput}/>
</Form.Group>
<Button type="submit" variant="secondary">Save This Recipe !</Button>
</Form>
)
};
}
export default RecipeFormContainer;
答案 0 :(得分:0)
看看您的代码,您的handleAddIngredients
是不正确的。您犯了两个错误:
您不是要从状态收集数据以放入ingredient
中。您的代码将创建一个空白ingredient
并将其放入数组。
ingredients
数组。您的代码从ingredients
中“提取”了this.state.ingredients
,但这是不可能的。您的ingredients
属于您的state
,而不是state.ingredients
。
代替做
let { ingredients } = this.state.ingredients
您可以
let { ingredients } = this.state
甚至
let ingredients = [ ...this.state.ingredients ]
所有修复之后,您的代码应如下所示:
handleAddIngredients = (e) => {
e.preventDefault();
//Extracting the values from the state
let { units, amounts, multiples, quantity, name } = this.state
// Inserting the values into the new ingredient
let ingredient = { units, amounts, multiples, quantity, name }
// Creating the copy
let ingredients = [ ... this.state.ingredients ]
// add the ingredient object into the ingredients array ( which is a property of state)
ingredients.push(ingredient);
// set the new array of ingredients in the state
this.setState({ingredients});
};