Réagir - Mettre à jour l'état dans le composant de classe en fonction du texte saisi par l'utilisateur après un clic sur le bouton
Je suis relativement nouveau dans React et je crée une application de recette de style liste de tâches. L'utilisateur doit pouvoir ajouter une nouvelle recette, supprimer une recette existante ou modifier une recette existante. J'ai des difficultés à écrire une fonction qui permet à l'utilisateur de cliquer sur le bouton Modifier, puis de soumettre un nouveau titre de recette et / ou de nouveaux ingrédients à cet élément de recette.
Voici le projet . Comment puis-je faire en sorte qu'après avoir cliqué sur l'un des boutons d'édition et soumis le formulaire, le titre de la recette / les ingrédients de cet élément de recette sont mis à jour pour afficher tout ce que l'utilisateur a soumis? J'ai une fonction appelée onSubmit
dans mon fichier App.js qui gère les nouveaux éléments de recette créés par l'utilisateur et les ajoute à la liste. J'essaie maintenant d'implémenter une fonction similaire appelée onEditSubmit
qui permet à l'utilisateur de mettre à jour les éléments de recette existants mais je suis bloqué.
Voici mon App.js où vit l'État:
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>
);
}
}
Et voici mon conteneur de fonctions Item.js pour les données. Ce conteneur fonctionne très bien lorsqu'il l' onSubmit
utilise pour ajouter une nouvelle recette. Mais quand onEditSubmit
tente de l' utiliser , je reçois une erreur, 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;
À peu près sûr que je fais une erreur Noob React, mais je ne suis pas sûr du problème.
Modifié pour corriger l'erreur de syntaxe dans la fonction onSubmitError: inputVal a changé en inputValEdit, ingrédientVal changé en ingrédientValEdit
Voici les composants fonctionnels pour 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;
Et voici le composant fonctionnel pour 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
});
}
vous définissez le items
champ d'état sur une chaîne. Vous devriez le changer en quelque chose comme:
onEditSubmit = (e) => {
e.preventDefault();
const {items, ingredients, inputVal, ingredientVal, editingIndex} = this.state;
items[editingIndex] = inputVal;
ingredients[editingIndex] = ingredientVal;
this.setState({
items,
ingredients,
inputVal: '',
ingredientVal: ''
});
}
Où editingIndex
vous pouvez stocker dans votre edit
fonction:setState({editingIndex: index}