React-da ene komponentiň ýagdaýyny çaga komponentinde üýtgetmek

Öňki sapakda maglumatlar bilen ýagdaý ene komponentde saklanyldy, çaga komponentler bolsa bu maglumatlary prop hökmünde alypdy.

Indi önümlerimizi üýtgetmek isleýändigimizi farz edeliň. Mysal üçin, önümi sebede goýýan düwmäni ýasaýaly. Başlangyçda önümlerimiziň sanawyna sebede ýa-da ýokdugyny görkezýän inCart meýdanyny goşalyň:

jsxconst initProds = [
  {id: id(), name: 'product1', cost: 100, inCart: false},
  {id: id(), name: 'product2', cost: 200, inCart: false},
  {id: id(), name: 'product3', cost: 300, inCart: false},
];

Products komponentinde önüm bilen tege ýene bir atyrbut inCart goşalyň:

jsxfunction Products() {
  const [prods, setProds] = useState(initProds);
  
  const items = prods.map(prod => {
    return <Product
      key   ={prod.id}
      name  ={prod.name}
      cost  ={prod.cost}
      inCart={prod.inCart}
    />;
  });
  
  return <div>
    {items}
  </div>;
}

Product çaga komponentinde sebet baradaky maglumaty we sebede goşmak üçin düwmäni çykyş etdirýäris:

jsxfunction Product({ id, name, cost, inCart }) {
  return <div>
    ady: <span>{name}</span>,
    bahasy: <span>{cost}</span>,
    <span>{inCart ? 'sebette' : 'sebette däl'}</span>
    <button>sebede</button>
  </div>;
}

Goşmagy amala aşyrmak

React düzgünlerine görä komponent öz proplaryny üýtgetmemelidir. Bu çaga komponentiň özüni inCart propyny üýtgedip, özüni sebede goýup bilmejekdigini aňladýar. Bu dogry däl.

Dogrusy ene komponentinden belli bir önümi sebede goýmak üçin öz ýagdaýy prods üýtgetmegini soramak bolar.

Geliň muny nädip edýändigine göz aýlanyşyk edeliň.

Ene komponentinde parametr hökmünde önümiň id-sini kabul edýän we bu önüm üçin inCart hassaýetini true üýtgedýän addToCart funksiýasyny ýasaýalyň:

jsxfunction addToCart(id) {
  setProds(prods.map(prod => {
    if (prod.id === id) {
      prod.inCart = true;
    }
    
    return prod;
  }));
}

Önüm bilen tege biz ýasalan funksiýany iberýän atributy we şeýle hem önümiň id-sini iberýän atributy goşalyň:

jsxconst items = prods.map(prod => {
  return <Product
    key      ={prod.id}
    id       ={prod.id}
    name     ={prod.name}
    cost     ={prod.cost}
    inCart   ={prod.inCart}
    addToCart={addToCart}
  />;
});

Görşüňiz ýaly, komponentleriň proplaryna diňe belli bir maglumatlary däl, eýsem funksiýalary hem iberip bolýar.

Products klasynyň netijeli kody aşakdaky ýaly bolar:

jsxfunction Products() {
  const [prods, setProds] = useState(initProds);
  
  function addToCart(id) {
    setProds(prods.map(prod => {
      if (prod.id === id) {
        prod.inCart = true;
      }
      
      return prod;
    }));
  }
  
  const items = prods.map(prod => {
    return <Product
      key      ={prod.id}
      id       ={prod.id}
      name     ={prod.name}
      cost     ={prod.cost}
      inCart   ={prod.inCart}
      addToCart={addToCart}
    />;
  });
  
  return <div>
    {items}
  </div>;
}

Indi çaga klasymyzda addToCart funksiýasy elýeterli bolar. Bu funksiýany düwmä basylanda çagyryp, oňa parametr hökmünde önümiň id-sini ibereliň:

jsxfunction Product({ id, name, cost, inCart, addToCart }) {
  return <div>
    ady: <span>{name}</span>,
    bahasy: <span>{cost}</span>,
    <span>{inCart ? 'sebette' : 'sebette däl'}</span>
    <button onClick={() => addToCart(id)}>sebede</button>
  </div>;
}

Netijede, nesilde düwmä basylanda eneniň funksiýasy çagyrylar we enäniň ýagdaýyny üýtgeder. Ene komponentiniň ýagdaýynyň üýtgemesi täzeden işläp we önümi täzeden çyzyp, oňa üýtgedilen propy iberer.

Задание 1

Öňki sapagyň User komponentini alyň. Onda ulanyjy üçin banka salýan düwme ýüze çykaryň.