Ku-render kwa Masharti

Components (vipengele) zako mara nyingi zitahitaji kuonyesha vitu tofauti kutegemea masharti tofauti. Katika React, unaweza ku-render JSX kwa masharti ukitumia sintaksia ya JavaScript kama kauli za if, na opereta za &&, na ? :.

You will learn

  • Jinsi ya kurudisha JSX tofauti kutegemea sharti
  • Jinsi ya kujumuisha au kutojumuisha kipande cha JSX kwa masharti
  • Njia mkato za kawaida za masharti utakazokutana nazo katika misimbo ya React

Kurudisha JSX kwa masharti

Tuseme una component ya PackingList inayo-render Item kadhaa, ambazo zinaweza kuwekewa alama kuwa zimepakiwa au la:

function Item({ name, isPacked }) {
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Orodha ya kupakia ya Sally Ride</h1>
      <ul>
        <Item
          isPacked={true}
          name="Suti ya angani"
        />
        <Item
          isPacked={true}
          name="Kofia yenye jani la dhahabu"
        />
        <Item
          isPacked={false}
          name="Picha ya Tam"
        />
      </ul>
    </section>
  );
}

Angalia kuwa baadhi ya components za Item zina prop yao ya isPacked iliyowekwa kuwa true badala ya false. Unataka kuongeza alama ya kupe (✅) kwenye vitu vilivyopakiwa kama isPacked={true}.

Unaweza kuandika hili kama kauli ya if/else kama hivi:

if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;

Kama prop ya isPacked ni true, msimbo huu hurudisha mti tofauti wa JSX. Kwa mabadiliko haya, baadhi ya vitu hupata alama ya kupe mwishoni:

function Item({ name, isPacked }) {
  if (isPacked) {
    return <li className="item">{name} ✅</li>;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Orodha ya kupakia ya Sally Ride</h1>
      <ul>
        <Item
          isPacked={true}
          name="Suti ya angani"
        />
        <Item
          isPacked={true}
          name="Kofia yenye jani la dhahabu"
        />
        <Item
          isPacked={false}
          name="Picha ya Tam"
        />
      </ul>
    </section>
  );
}

Jaribu kuhariri kinachorudishwa katika kila hali, na uone jinsi matokeo yanavyobadilika!

Angalia jinsi unavyounda mantiki ya matawi kwa kutumia kauli za if na return za JavaScript. Katika React, mtiririko wa udhibiti (kama masharti) hushughulikiwa na JavaScript.

Kurudisha bila kitu kwa masharti kwa kutumia null

Katika baadhi ya hali, hautataka ku-render chochote kabisa. Kwa mfano, tuseme hautaki kuonyesha vitu vilivyopakiwa hata kidogo. Component lazima irudishe kitu fulani. Katika hali hii, unaweza kurudisha null:

if (isPacked) {
return null;
}
return <li className="item">{name}</li>;

Kama isPacked ni true, component itarudisha bila kitu, null. Vinginevyo, itarudisha JSX ya ku-render.

function Item({ name, isPacked }) {
  if (isPacked) {
    return null;
  }
  return <li className="item">{name}</li>;
}

export default function PackingList() {
  return (
    <section>
      <h1>Orodha ya kupakia ya Sally Ride</h1>
      <ul>
        <Item
          isPacked={true}
          name="Suti ya angani"
        />
        <Item
          isPacked={true}
          name="Kofia yenye jani la dhahabu"
        />
        <Item
          isPacked={false}
          name="Picha ya Tam"
        />
      </ul>
    </section>
  );
}

Kwa vitendo, kurudisha null kutoka kwa component si jambo la kawaida kwa sababu linaweza kumshangaza mtengenezaji anayejaribu kuii-render. Mara nyingi zaidi, ungejumuisha au kutojumuisha component kwa masharti katika JSX ya component-mzazi. Hivi ndivyo ya kufanya hivyo!

Kujumuisha JSX kwa masharti

Katika mfano uliopita, ulidhibiti ni mti gani wa JSX (kama upo!) ungerudishwa na component. Huenda tayari umeona urudufu fulani katika matokeo ya render:

<li className="item">{name} ✅</li>

unafanana sana na

<li className="item">{name}</li>

Matawi yote mawili ya masharti hurudisha <li className="item">...</li>:

if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;

Ingawa urudufu huu si wenye madhara, unaweza kufanya msimbo wako kuwa mgumu zaidi kuutunza. Vipi kama unataka kubadilisha className? Ungelazimika kufanya hivyo katika sehemu mbili za msimbo wako! Katika hali kama hii, ungeweza kujumuisha JSX kidogo kwa masharti ili kufanya msimbo wako uwe DRY zaidi.

Opereta ya masharti (ternary) (? :)

JavaScript ina sintaksia fupi ya kuandika usemi wa masharti — opereta ya masharti au “opereta ya ternary”.

Badala ya hii:

if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>;

Unaweza kuandika hii:

return (
<li className="item">
{isPacked ? name + ' ✅' : name}
</li>
);

Unaweza kuisoma kama “kama isPacked ni true, basi (?) render name + ' ✅', vinginevyo (:) render name”.

Deep Dive

Je, mifano hii miwili inalingana kabisa?

Kama unatoka kwenye msingi wa programu inayoegemea object (object-oriented programming), unaweza kudhani kuwa mifano miwili hapo juu ina tofauti ndogo kwa sababu mmoja wao unaweza kuunda “instances” mbili tofauti za <li>. Lakini elementi za JSX si “instances” kwa sababu hazishikilii state (hali) yoyote ya ndani na si nodi halisi za DOM. Ni maelezo mepesi, kama ramani za ujenzi. Hivyo mifano hii miwili, kwa hakika, inalingana kabisa. Kuhifadhi na Kuweka Upya State inaeleza kwa kina jinsi hili linavyofanya kazi.

Sasa tuseme unataka kufunga maandishi ya kitu kilichokamilika ndani ya tagi nyingine ya HTML, kama <del> ili kuyakata. Unaweza kuongeza mistari mipya na mabano zaidi ili iwe rahisi kupachika JSX zaidi katika kila hali:

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {isPacked ? (
        <del>
          {name + ' ✅'}
        </del>
      ) : (
        name
      )}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Orodha ya kupakia ya Sally Ride</h1>
      <ul>
        <Item
          isPacked={true}
          name="Suti ya angani"
        />
        <Item
          isPacked={true}
          name="Kofia yenye jani la dhahabu"
        />
        <Item
          isPacked={false}
          name="Picha ya Tam"
        />
      </ul>
    </section>
  );
}

Mtindo huu hufanya kazi vizuri kwa masharti rahisi, lakini utumie kwa kiasi. Kama components zako zinakuwa na msongamano kwa markup nyingi sana ya masharti iliyopachikwa, fikiria kutoa components-watoto ili kusafisha mambo. Katika React, markup ni sehemu ya msimbo wako, hivyo unaweza kutumia zana kama vigezo na functions kuratibu semi zenye utata.

Opereta ya kimantiki ya AND (&&)

Njia mkato nyingine ya kawaida utakayokutana nayo ni opereta ya kimantiki ya AND (&&) ya JavaScript. Ndani ya components za React, mara nyingi hujitokeza wakati unataka ku-render JSX fulani wakati sharti ni true, au render bila kitu vinginevyo. Kwa &&, ungeweza ku-render alama ya kupe kwa masharti tu kama isPacked ni true:

return (
<li className="item">
{name} {isPacked && '✅'}
</li>
);

Unaweza kuisoma kama “kama isPacked, basi (&&) render alama ya kupe, vinginevyo, render bila kitu”.

Hii hapa ikifanya kazi:

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Orodha ya kupakia ya Sally Ride</h1>
      <ul>
        <Item
          isPacked={true}
          name="Suti ya angani"
        />
        <Item
          isPacked={true}
          name="Kofia yenye jani la dhahabu"
        />
        <Item
          isPacked={false}
          name="Picha ya Tam"
        />
      </ul>
    </section>
  );
}

Usemi wa && wa JavaScript hurudisha thamani ya upande wake wa kulia (katika hali yetu, alama ya kupe) kama upande wa kushoto (sharti letu) ni true. Lakini kama sharti ni false, usemi mzima unakuwa false. React huchukulia false kama “shimo” katika mti wa JSX, kama tu null au undefined, na hairenderi chochote mahali pake.

Pitfall

Usiweke namba upande wa kushoto wa &&.

Ili kupima sharti, JavaScript hubadilisha upande wa kushoto kuwa boolean kiotomatiki. Hata hivyo, kama upande wa kushoto ni 0, basi usemi mzima unapata thamani hiyo (0), na React itaenda mbele kwa furaha ku-render 0 badala ya bila kitu.

Kwa mfano, kosa la kawaida ni kuandika msimbo kama messageCount && <p>New messages</p>. Ni rahisi kudhani kuwa hairenderi chochote wakati messageCount ni 0, lakini kwa hakika inarender 0 yenyewe!

Ili kurekebisha hilo, fanya upande wa kushoto kuwa boolean: messageCount > 0 && <p>New messages</p>.

Kukabidhi JSX kwa kigezo kwa masharti

Wakati njia mkato zinakwamisha kuandika msimbo wa kawaida, jaribu kutumia kauli ya if na kigezo. Unaweza kukabidhi upya vigezo vilivyofafanuliwa kwa let, hivyo anza kwa kutoa maudhui chaguo-msingi unayotaka kuonyesha, jina:

let itemContent = name;

Tumia kauli ya if kukabidhi upya usemi wa JSX kwa itemContent kama isPacked ni true:

if (isPacked) {
itemContent = name + " ✅";
}

Mabano ya curly hufungua “dirisha la kuingia JavaScript”. Pachika kigezo kwa mabano ya curly katika mti wa JSX unaorudishwa, ukipachika usemi uliokokotolewa awali ndani ya JSX:

<li className="item">
{itemContent}
</li>

Mtindo huu ni wenye maneno mengi zaidi, lakini pia ni unaonyumbulika zaidi. Hii hapa ikifanya kazi:

function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = name + " ✅";
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Orodha ya kupakia ya Sally Ride</h1>
      <ul>
        <Item
          isPacked={true}
          name="Suti ya angani"
        />
        <Item
          isPacked={true}
          name="Kofia yenye jani la dhahabu"
        />
        <Item
          isPacked={false}
          name="Picha ya Tam"
        />
      </ul>
    </section>
  );
}

Kama ilivyokuwa awali, hii hufanya kazi si tu kwa maandishi, bali pia kwa JSX yoyote ile:

function Item({ name, isPacked }) {
  let itemContent = name;
  if (isPacked) {
    itemContent = (
      <del>
        {name + " ✅"}
      </del>
    );
  }
  return (
    <li className="item">
      {itemContent}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Orodha ya kupakia ya Sally Ride</h1>
      <ul>
        <Item
          isPacked={true}
          name="Suti ya angani"
        />
        <Item
          isPacked={true}
          name="Kofia yenye jani la dhahabu"
        />
        <Item
          isPacked={false}
          name="Picha ya Tam"
        />
      </ul>
    </section>
  );
}

Kama hufahamu JavaScript vizuri, aina hii mbalimbali ya mitindo inaweza kuonekana kuwa nyingi mno mwanzoni. Hata hivyo, kuzijifunza kutakusaidia kusoma na kuandika msimbo wowote wa JavaScript — na si components za React tu! Chagua ule unaoupendelea kwa kuanzia, kisha rejea kwenye rejeleo hili tena kama utasahau jinsi zile nyingine zinavyofanya kazi.

Recap

  • Katika React, unadhibiti mantiki ya matawi kwa JavaScript.
  • Unaweza kurudisha usemi wa JSX kwa masharti kwa kauli ya if.
  • Unaweza kuhifadhi JSX fulani kwa kigezo kwa masharti kisha kuijumuisha ndani ya JSX nyingine kwa kutumia mabano ya curly.
  • Katika JSX, {cond ? <A /> : <B />} inamaanisha “kama cond, render <A />, vinginevyo <B />”.
  • Katika JSX, {cond && <A />} inamaanisha “kama cond, render <A />, vinginevyo bila kitu”.
  • Njia mkato ni za kawaida, lakini si lazima uzitumie kama unapendelea if ya kawaida.

Challenge 1 of 3:
Onyesha aikoni kwa vitu visivyokamilika kwa ? :

Tumia opereta ya masharti (cond ? a : b) ku-render ❌ kama isPacked si true.

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Orodha ya kupakia ya Sally Ride</h1>
      <ul>
        <Item
          isPacked={true}
          name="Suti ya angani"
        />
        <Item
          isPacked={true}
          name="Kofia yenye jani la dhahabu"
        />
        <Item
          isPacked={false}
          name="Picha ya Tam"
        />
      </ul>
    </section>
  );
}