Kubadilisha State ya Mzazi Katika Kijenzi Kijana katika React

Katika somo lililopita tulikuwa na data ya state ilihifadhiwa katika kijenzi kizazi, na vijenzi vya watoto vilipata data hiyo kwa njia ya props.

Wacha sasa tutake kubadilisha bidhaa zetu. Tufanye, kwa mfano, kitufe ambacho kitakuwa kiweke bidhaa yetu kwenye kikapu. Kuanza tuongeze kwenye safu yetu ya bidhaa uwanja inCart, unaoonyesha, kwenye kikapu bidhaa iko au la:

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},
];

Katika kijenzi Products kwenye tag na bidhaa tuongeze sifa nyingine inCart:

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>;
}

Wacha kwenye kijenzi kijana Product tufanye uwasilishaji wa taarifa kuhusu kikapu na kitufe cha kuongeza kwenye kikapu:

jsxfunction Product({ id, name, cost, inCart }) {
  return <div>
    name: <span>{name}</span>,
    cost: <span>{cost}</span>,
    <span>{inCart ? 'in cart' : 'not in cart'}</span>
    <button>to cart</button>
  </div>;
}

Tutekeleze Kuongeza

Kulingana na sheria za React kijenzi haifai kubadilisha props zake. Hii inamaanisha kuwa kijenzi kijana hakiwezi kujiweka yenyewe kwenye kikapu, kwa kubadilisha prop inCart. Hii si sahihi.

Ni sahihi kuomba kijenzi kizazi kubadilisha state yake prods, kuweka bidhaa fulani kwenye kikapu.

Wacha tuangalie jinsi hii inafanyika.

Kwenye kijenzi kizazi tufanye funkta addToCart, ambayo inakubali kigezo id cha bidhaa na kwa bidhaa hiyo inabadilisha sifa inCart kuwa true:

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

Kwenye tag na bidhaa tuongeze sifa, ambayo tutapeana funkta yetu tuliyounda, na pia sifa, ambayo tutapeana id ya bidhaa:

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

Kama unavyoona, kwenye props za vijenzi unaweza kupeana sio tu data fulani, lakini pia kazi.

Msimbo wa mwisho wa darasa Products utakuwa kama ifuatavyo:

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>;
}

Sasa kwenye darasa la watoto tutakuwa na ufikiaji wa kazi addToCart. Wacha tuite kazi hii kwa kubonyeza kitufe, tukipeana kigezo id ya bidhaa:

jsxfunction Product({ id, name, cost, inCart, addToCart }) {
  return <div>
    name: <span>{name}</span>,
    cost: <span>{cost}</span>,
    <span>{inCart ? 'in cart' : 'not in cart'}</span>
    <button onClick={() => addToCart(id)}>to cart</button>
  </div>;
}

Itakuwa, kwamba kwa kubonyeza kitufe kwenye kijana itaita kazi ya mzazi, ambayo itabadilisha state ya mzazi. Kubadilika kwa state ya mzazi kitasababisha upyaaji na kuchora upya bidhaa yetu, tukimpeana prop iliyobadilishwa.

Задание 1

Chukua kijenzi User kutoka somo lililopita. Fanya ili ndani yake ionekane kitufe kwa kukataza mtumiaji.