Redigering af forældre-state i en underkomponent i React
Lad os nu redigere vores produkter ved hjælp af inputfelter. For at gøre dette skal vi lave en knap i underkomponenten.
Ved første klik på denne knap, lad os i stedet for navnet og prisen på produktet vise inputfelter til deres redigering, og ved andet klik viser teksterne igen i stedet for inputfelterne.
Lad os foretage en ændring i arrayet med produkter ved at tilføje
egenskaben isEdit (og for enkelhedens skyld fjerner vi
arbejdet med indkøbskurven):
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
Lad os lave en knap til redigering i produktet:
function Product({ id, name, cost, isEdit }) {
return <div>
navn: <span>{name}</span>
pris: <span>{cost}</span>
<button>rediger</button>
</div>;
}
Lad os gøre sådan, at ved et klik på denne knap
kaldes en eller anden funktion toggleMode,
som er sendt fra forældrekomponenten:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
navn: <span>{name}</span>
pris: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
rediger
</button>
</div>;
}
Vi har ikke implementeret toggleMode endnu,
men vi ved, at den vil være placeret
i forældrekomponenten, modtage
id på produktet som parameter og ændre egenskaben isEdit
på produktet til den modsatte.
Lad os også gøre sådan, at knappens tekst skifter ved hvert klik:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
navn: <span>{name}</span>
pris: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
{isEdit ? 'gem': 'rediger'}
</button>
</div>;
}
Lad os nu gøre sådan, at i redigerings tilstanden har vi inputfelter med data, og i normal tilstand - spans:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
navn: {isEdit ? <input value={name} /> : <span>{name}</span>}
pris: {isEdit ? <input value={cost} /> : <span>{cost}</span>}
<button onClick={() => toggleMode(id)}>
{isEdit ? 'gem': 'rediger'}
</button>
</div>;
}
Lad os knytte onChange eventet til vores inputfelter,
hvor vi vil kalde en eller anden forældre
funktion editProd:
function Product({ id, name, cost, isEdit, toggleMode, editProd }) {
return <div>
navn: {
isEdit
? <input value={name} onChange={event => editProd(id, 'name', event)} />
: <span>{ name }</span>
}
pris: {
isEdit
? <input value={cost} onChange={event => editProd(id, 'cost', event)} />
: <span>{ cost }</span>
}
<button onClick={() => toggleMode(id)}>
{isEdit ? 'gem': 'rediger'}
</button>
</div>;
}
Komponenten Products
Lad os nu gå videre til komponenten Products.
Lad os implementere funktionen toggleMode i den:
function toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
Lad os også implementere funktionen editProd i den:
function editProd(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
Lad os sende vores funktioner toggleMode og editProd
som attributter til produkt-tagget:
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 endelige kode for komponenten Products
vil blive som følger:
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>;
}
Praktiske opgaver
Udfør lignende operationer med komponenterne
Users og User, som du har oprettet
i de foregående lektioner.