Modification de l'état parent dans un composant enfant dans React
Modifions maintenant nos produits à l'aide de champs de saisie. Pour cela, dans le composant enfant, créeons un bouton.
Lors du premier clic sur ce bouton, que des champs de saisie pour leur modification apparaissent à la place du nom et du prix du produit, et lors du deuxième clic, que les textes réapparaissent à la place des champs de saisie.
Apportons une modification au tableau de produits en ajoutant
une propriété isEdit (et retirons le travail avec le panier
par souci de simplicité) :
const initProds = [
{id: id(), name: 'product1', cost: 100, isEdit: false},
{id: id(), name: 'product2', cost: 200, isEdit: false},
{id: id(), name: 'product3', cost: 300, isEdit: false},
];
Composant Product
Créeons un bouton pour la modification dans le produit :
function Product({ id, name, cost, isEdit }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button>edit</button>
</div>;
}
Faisons en sorte qu'un clic sur ce bouton
déclenche une fonction toggleMode,
transmise depuis le composant parent :
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
edit
</button>
</div>;
}
Nous n'avons pas encore l'implémentation de toggleMode,
mais nous savons qu'elle se situera
dans le composant parent, acceptera en paramètre
l'id du produit et changera la propriété isEdit
du produit à sa valeur opposée.
Faisons également en sorte que le texte du bouton change à chaque clic :
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
{isEdit ? 'save': 'edit'}
</button>
</div>;
}
Faisons maintenant en sorte qu'en mode modification, nous ayons des champs de saisie avec les données, et en mode normal - des spans :
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
name: {isEdit ? <input value={name} /> : <span>{name}</span>}
cost: {isEdit ? <input value={cost} /> : <span>{cost}</span>}
<button onClick={() => toggleMode(id)}>
{isEdit ? 'save': 'edit'}
</button>
</div>;
}
Associons à nos champs de saisie l'événement onChange,
dans lequel nous appellerons une fonction parente
editProd :
function Product({ id, name, cost, isEdit, toggleMode, editProd }) {
return <div>
name: {
isEdit
? <input value={name} onChange={event => editProd(id, 'name', event)} />
: <span>{ name }</span>
}
cost: {
isEdit
? <input value={cost} onChange={event => editProd(id, 'cost', event)} />
: <span>{ cost }</span>
}
<button onClick={() => toggleMode(id)}>
{isEdit ? 'save': 'edit'}
</button>
</div>;
}
Composant Products
Passons maintenant au composant Products.
Implémentons-y la fonction toggleMode :
function toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
Implémentons également la fonction editProd :
function editProd(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
Transmettons nos fonctions toggleMode et editProd
en tant qu'attributs à la balise du produit :
const items = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name={prod.name}
cost={prod.cost}
isEdit={prod.isEdit}
toggleMode={toggleMode}
editProd={editProd}
/>;
});
Le code final du composant Products
sera le suivant :
function Products() {
const [prods, setProds] = useState(initProds);
function toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
function editProd(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
const result = prods.map(prod => {
return <Product
key ={prod.id}
id ={prod.id}
name={prod.name}
cost={prod.cost}
isEdit={prod.isEdit}
toggleMode={toggleMode}
editProd={editProd}
/>;
});
return <div>
{result}
</div>;
}
Tâches pratiques
Répétez les opérations similaires avec les composants
Users et User, créés par vous
dans les leçons précédentes.