Redigering av föräldratillstånd i en barnkomponent i React
Låt oss nu redigera våra produkter med hjälp av inmatningsfält. För att göra detta, skapa en knapp i barnkomponenten.
Vid första klicket på denna knapp, låt oss istället för namn och pris på produkten visa inmatningsfält för att redigera dem, och vid andra klicket visa texterna igen istället för inmatningsfälten.
Låt oss ändra arrayen med produkter genom att lägga till
egenskapen isEdit (och ta bort kundvagnsfunktionen
för enkelhetens skull):
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},
];
Komponenten Product
Låt oss skapa en knapp för redigering i produkten:
function Product({ id, name, cost, isEdit }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button>edit</button>
</div>;
}
Låt oss göra så att när man klickar på denna knapp
anropas en funktion toggleMode,
som skickats från förälderkomponenten:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
name: <span>{name}</span>
cost: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
edit
</button>
</div>;
}
Vi har ännu ingen implementation av toggleMode,
men vi vet att den kommer att finnas
i förälderkomponenten, ta id för produkten som parameter och ändra egenskapen isEdit
för produkten till motsatt värde.
Låt oss också göra så att knappens text ändras vid varje klick:
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>;
}
Låt oss nu göra så att i redigeringsläget visas inmatningsfält med data, och i normalt läge - spann-element:
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>;
}
Låt oss koppla onChange-händelsen till våra inmatningsfält,
där vi kommer att anropa en förälderfunktion
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>;
}
Komponenten Products
Låt oss nu gå till komponenten Products.
Låt oss implementera funktionen toggleMode i den:
function toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
Låt oss också implementera funktionen editProd i den:
function editProd(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
Låt oss skicka våra funktioner toggleMode och editProd
som attribut till produkt-taggen:
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}
/>;
});
Den slutgiltiga koden för komponenten Products
kommer att se ut så här:
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>;
}
Praktiska uppgifter
Utför liknande operationer med komponenterna
Users och User, som du skapade
i tidigare lektioner.