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):
jsxconst 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:
jsxfunction 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:
jsxfunction 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:
jsxfunction 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:
jsxfunction 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:
jsxfunction 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:
jsxfunction toggleMode(id) {
setProds(prods.map(prod => {
if (prod.id === id) {
prod.isEdit = !prod.isEdit;
}
return prod;
}));
}
Rakendame selles ka funktsiooni editProd:
jsxfunction 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:
jsxconst 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:
jsxfunction 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.