Vanema komponendi oleku muutmine lapse komponendis Reactis
Muudame nüüd oma tooteid sisendväljade abil. Selleks teeme lapse komponendis nupu.
Esimesel vajutusel sellele nupule kuvagu toote nime ja hinna asemel nende muutmiseks mõeldud sisendväljad, ning teisel vajutusel kuvagu sisendväljade asemel uuesti tekstid.
Teeme muudatuse tootemassiivis, lisades
omaduse isEdit (ja ostukorvi töö
eemaldame lihtsuse mõttes):
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},
];
Komponent Product
Teeme tootes nupu muutmiseks:
function Product({ id, name, cost, isEdit }) {
return <div>
nimi: <span>{name}</span>
hind: <span>{cost}</span>
<button>muuda</button>
</div>;
}
Teeme nii, et selle nupu vajutamisel
kutsutakse välja mingi funktsioon toggleMode,
mis on edastatud vanemkomponendist:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
nimi: <span>{name}</span>
hind: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
muuda
</button>
</div>;
}
Meil pole veel toggleMode rakendust,
kuid me teame, et see asub
vanemkomponendis, võtab parameetrina
toote id ja muudab toote omadust isEdit
vastupidiseks.
Teeme ka nii, et nupu tekst muutuks iga vajutusega:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
nimi: <span>{name}</span>
hind: <span>{cost}</span>
<button onClick={() => toggleMode(id)}>
{isEdit ? 'salvesta': 'muuda'}
</button>
</div>;
}
Teeme nüüd nii, et muutmise režiimis oleksid meil andmetega sisendväljad, ja tavarežiimis - span elemendid:
function Product({ id, name, cost, isEdit, toggleMode }) {
return <div>
nimi: {isEdit ? <input value={name} /> : <span>{name}</span>}
hind: {isEdit ? <input value={cost} /> : <span>{cost}</span>}
<button onClick={() => toggleMode(id)}>
{isEdit ? 'salvesta': 'muuda'}
</button>
</div>;
}
Seome oma sisendväljadega sündmuse onChange,
milles kutsume välja mingi vanema
funktsiooni editProd:
function Product({ id, name, cost, isEdit, toggleMode, editProd }) {
return <div>
nimi: {
isEdit
? <input value={name} onChange={event => editProd(id, 'name', event)} />
: <span>{ name }</span>
}
hind: {
isEdit
? <input value={cost} onChange={event => editProd(id, 'cost', event)} />
: <span>{ cost }</span>
}
<button onClick={() => toggleMode(id)}>
{isEdit ? 'salvesta': 'muuda'}
</button>
</div>;
}
Komponent Products
Liigume nüüd komponenti Products.
Rakendame selles funktsiooni toggleMode:
function toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
Rakendame selles ka funktsiooni editProd:
function editProd(id, field, event) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod[field] = event.target.value;
}
return prod;
}));
}
Edastame oma
funktsioonid toggleMode ja editProd
toote elemendile atribuutidena:
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}
/>;
});
Komponendi Products lõplik kood
saab järgmiseks:
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>;
}
Praktilised ülesanded
Tehke samasugused toimingud komponentidega
Users ja User, mille te
loosite eelmistes õppetundides.