ການສະແດງຜົນແບບມີເງື່ອນໄຂ

component ຂອງທ່ານມັກຈະຕ້ອງສະແດງສິ່ງຕ່າງໆຂຶ້ນກັບແຕ່ລະເງື່ອນໄຂ. ໃນ React ທ່ານສາມາດສະແດງຜົນ JSX ຢ່າງມີເງື່ອນໄຂໂດຍໃຊ້ syntax JavaScript ເຊັ່ນ if statement, &&, ແລະ ? : operators.

You will learn

  • ວິທີ return JSX ທີ່ແຕກຕ່າງກັນຕາມເງື່ອນໄຂ
  • ວິທີລວມ ຫຼື ແຍກຊີ້ນສ່ວນຂອງ JSX ຢ່າງມີເງື່ອນໄຂ
  • ທາງລັດ syntax ທີ່ມີເງື່ອນໄຂທົ່ວໄປທີ່ທ່ານຈະໄດ້ພົບໃນ React codebases

ສົ່ງຄືນ JSX ແບບມີເງື່ອນໄຂ

ສົມມຸດວ່າທ່ານມີ component PackingList ທີ່ສະແດງ Item ຫຼາຍລາຍການ, ຊື່ງສາມາດເຮັດເຄື່ອງໝາຍວ່າແພັກແລ້ວ ຫຼື ບໍ່:

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

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

ສັງເກດວ່າມີ component Item ບາງໂຕມີ prop isPacked ເປັນ true ແທນທີ່ຈະເປັນ false. ທ່ານຕ້ອງການເພີ່ມເຄື່ອງໝາຍຕິກ (✔) ລົງໃນລາຍການທີ່ຖືກແພັກຖ້າ isPacked={true}.

ທ່ານສາມາດຂຽນເປັນ if/else statement ດັ່ງນີ້:

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

ຖ້າ prop isPacked ເປັນ true, code ນີ້ ຈະຄືນຄ່າ JSX tree ທີ່ແຕກຕ່າງກັນ. ດ້ວຍການປ່ຽນແປງນີ້, ບາງລາຍການມີເຄື່ອງໝາຍຕິກໃນຕອນທ້າຍ:

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>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

ລອງແກ້ໄຂສິ່ງທີ່ return ໃນທັງສອງກໍລະນີ, ແລະ ເບິ່ງວ່າຜົນລັບຈະປ່ຽນແປງແນວໃດ!

ສັງເກດວ່າທ່ານກຳລັງສ້າງ branching logic ດ້ວຍ if ແລະ return statement ຂອງ JavaScript. ໃນ React, flow ການຄວບຄຸມ (ເຊັ່ນ ເງື່ອນໄຂ) ແມ່ນຈັດການໂດຍ JavaScript.

ການ Return ທີ່ບໍ່ມີຄ່າດ້ວຍ null ຢ່າງມີເງື່ອນໄຂ

ໃນບາງສະຖານະການ, ທ່ານບໍ່ສາມາດສະແດງສິ່ງຕ່າງໆໄດ້. ຕົວຢ່າງ, ທ່ານບໍ່ຕ້ອງການສະແດງລາຍການທີແພັກແລ້ວເລີຍ. Component ຕ້ອງ return ບາງຢ່າງ. ໃນກໍລະນີນີ້, ທ່ານສາມາດ return null:

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

ຖ້າ isPacked ເປັນ true, component ຈະບໍ່ return ຫຍັງ, null. ກົງກັນຂ້າມ, ມັນຈະ return JSX ເພື່ອສະແດງຜົນ.

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

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

ໃນທາງປະຕິບັດ, ການ return ດ້ວຍ null ຈາກ component ເປັນເລື່ອງທີ່ບໍ່ປົກະຕິເພາະມັນອາດຈະເຮັດໃຫ້ນັກພັດທະນາປະຫຼາດໃຈທີ່ພະຍາຍາມຈະສະແດງມັນ. ສ່ວນຫຼາຍ, ທ່ານຈະລວມ ຫຼື ແຍກ component ໃນ parent component ຂອງ JSX. ນີ້ແມ່ນວິທີການ!

ແບບມີເງື່ອນໄຂລວມມີ JSX

ໃນຕົວຢ່າງກ່ອນໜ້ານີ້, ທ່ານໄດ້ຄວບຄຸມ (ຖ້າມີ!) JSX tree ທີ່ return ໂດຍ component. ທ່ານອາດຈະສັງເກດເຫັນການສະແດງຜົນທີ່ຊໍ້າກັນ:

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

ຄ້າຍຄືກັບ

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

ທັງສອງເງື່ອນໄຂ branch ແມ່ນ return <li className="item">...</li>:

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

ເຖິງວ່າການເຮັດຊໍ້ານີ້ຈະບໍ່ເປັນອັນຕະລາຍ, ແຕ່ມັນອາດຈະເຮັດໃຫ້ code ຂອງທ່ານຍາກໃນການ maintain. ຖ້າທ່ານຕ້ອງການປ່ຽນ className ເດ? ທ່ານຈະຕ້ອງໄດ້ເຮັດໃນສອງບ່ອນຂອງ code ທ່ານ! ໃນສະຖານະການແບບນີ້, ທ່ານສາມາດລວມ JSX ນ້ອຍແບບມີເງື່ອນໄຂເພື່ອເຮັດໃຫ້ code ຂອງທ່ານ DRY ຫຼາຍຂຶ້ນ.

Conditional (ternary) operator (? :)

JavaScript ມີ syntax ທີ່ກະຊັບສຳລັບຂຽນ expression ເງື່ອນໄຂ — conditional operator ຫຼື “ternary operator”.

ແທນທີ່ຈະເປັນແບບນີ້:

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

ທ່ານສາມາດຂຽນແບບນີ້:

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

ທ່ານສາມາດອ່ານເປັນ “ຖ້າ isPacked ເປັນ true, ຈາກນັ້ນ (?) ສະແດງ name + ' ✔', ຖ້າບໍ່ດັ່ງນັ້ນ (:) ສະແດງ name.

Deep Dive

ທັງສອງຕົວຢ່າງນີ້ຄືກັນທັງໝົດບໍ່?

ຖ້າທ່ານມາຈາກພື້ນຖານການຂຽນໂປຣແກຣມເຊີງວັດຖຸ, ​ທ່ານອາດຈະຄິດວ່າສອງຕົວຢ່າງດ້ານເທິງມີຄວາມແຕກຕ່າງກັນໜ້ອຍໜຶ່ງເພາະວ່າຕົວຢ່າງໜຶ່ງອາດຈະສ້າງ “instance” ຂອງ <li> ສອງຕົວຢ່າງທີ່ແຕກຕ່າງກັນ. ແຕ່ JSX element ບໍ່ແມ່ນ “instances” ເພາະວ່າບໍ່ມີ state ພາຍໃນໃດໆ ແລະ ບໍ່ແມ່ນ DOM nodes ແທ້. ເປັນຄຳອະທິບາຍສັ້ນໆເຊັ່ນ blueprints. ສະນັ້ນສອງຕົວຢ່າງນີ້, ໃນຄວາມເປັນຈິງ, ແມ່ນ ທຽບເທົ່າກັນໝົດ. ການຮັກສາ ແລະ ລີເຊັດ State ມີລາຍລະອຽດກ່ຽວກັບວິທີການເຮັດວຽກນີ້.

ສົມມຸດວ່າທ່ານຕ້ອງການລວມຂໍ້ຄວາມລາຍການທີ່ສຳເລັດລົງໃນແທັກ HTML ເຊັ່ນ <del> ເພື່ອຂີດຂ້າ. ທ່ານສາມາດເພີ່ມແຖວໃໝ່ ແລະ ວົງເລັບເພື່ອໃຫ້ຊ້ອນ JSX ໃນແຕ່ລະກໍລະນີໄດ້ງ່າຍຂຶ້ນ.

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

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

ແບບນີ້ໃຊ້ໄດ້ດີກັບເງື່ອນໄຂງ່າຍໆ, ແຕ່ໃຊ້ໃນປະລິມານທີ່ເໝາະສົມ. ຖ້າ component ຂອງທ່ານເລີ່ມຫຍຸ້ງດ້ວຍ markup ແບບມີເງື່ອນໄຂທີ່ຊ້ອນກັນຫຼາຍເກີນໄປໃຫ້ລອງແຍກ child component ເພື່ອລ້າງຂໍ້ມູນ. ໃນ React, markup ເປັນສ່ວນໜຶ່ງຂອງ code ທ່ານ, ສະນັ້ນທ່ານສາມາດໃຊ້ເຄື່ອງມືເຊັ່ນ: ຕົວແປ ແລະ ຟັງຊັ່ນເພື່ອຈັດລະບຽບ expression ທີ່ຊັບຊ້ອນໄດ້.

Logic ແລະ operator (&&)

ທາງລັດທົ່ວໄປທີ່ທ່ານຈະໄດ້ພົບຄືຕົວດຳເນີນການ JavaScript logical ແລະ (&&) operator. ພາຍໃນ component React, ມັກຈະເກີດເມື່ອທ່ານຕ້ອງການສະແດງຜົນບາງ JSX ເມື່ອພົບເງື່ອນໄຂທີ່ເປັນຈິງ, ຫຼື ສະແດງຜົນຢ່າງອື່ນ. ຍ້ອນ && ທ່ານສາມາດສະແດງຜົນເຄື່ອງໝາຍຕິກຕາມເງື່ອນໄຂໃດກໍໄດ້ເມືອ isPacked ເປັນ true:

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

ທ່ານສາມາດອ່ານສິ່ງນີ້ເປັນ “ຖ້າ isPacked, ຈາກນັ້ນ (&&) ສະແດງຜົນເຄື່ອງໝາຍຕິກ, ນອກນັ້ນ, ບໍ່ສະແດງຜົນຫຍັງ”.

ນີ້ຄືວິທີການ:

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

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

JavaScript && expression ສົ່ງຄ່າທາງເບື້ອງຂວາ (ໃນກໍລະນີຂອງເຮົາ, ເຄື່ອງໝາຍຕິກ) ຖ້າເບື້ອງຊ້າຍ (ເງື່ອນໄຂຂອງເຮົາ) ເປັນ true. ແຕ່ຖ້າເງື່ອນໄຂເປັນ false, expression ທັງໝົດຈະເປັນ false. React ຖືວ່າ false ເປັນ “ຂຸມ” ໃນ JSX tree, ເຊັ່ນດຽວກັນກັບ null ຫຼື undefined, ແລະ ບໍ່ສະແດງຜົນຫຍັງເລີຍ.

Pitfall

ຫ້າມໃສ່ໂຕເລກຢູ່ເບື້ອງຊ້າຍຂອງ &&.

ເພື່ອທົດສອບເງື່ອນໄຂ, JavaScript ແປງເບື້ອງຊ້າຍມືໃຫ້ເປັນ boolean ໂດຍອັດຕະໂນມັດ. ເຖິງຢ່າງໃດກໍຕາມ, ຖ້າເບື້ອງຊ້າຍມືເປັນ 0, ຈາກນັ້ນ expression ທັງໝົດຈະໄດ້ຮັບຄ່ານັ້ນ (0), ແລະ React ຈະສະແດງຄ່າ 0 ແທນທີ່ຈະບໍ່ມີຫຍັງເລີຍ.

ຕົວຢ່າງ, ຂໍ້ຜີດພາດທົ່ວໄປທີ່ຂຽນ code ເຊັ່ນ messageCount && <p>New messages</p>. ເປັນເລື່ອງງ່າຍທີ່ຈະສັນນິຖານວ່າມັນບໍ່ສະແດງຜົນຫຍັງເມື່ອ messageCount ເປັນ 0, ແຕ່ຄວາມເປັນຈິງມັນສະແດງຜົນເປັນ 0 ເອງ!

ເພື່ອແກ້ໄຂ, ເຮັດໃຫ້ເບື້ອງຊ້າຍມືເປັນ boolean: messageCount > 0 && <p>New messages</p>.

ການກຳນົດຄ່າ JSX ໃຫ້ຕົວແປແບບມີເງື່ອນໄຂ

ເມື່ອທາງລັດຂັດຂວາງການຂຽນ code ແບບທຳມະດາ, ລອງໃຊ້ if statement ແລະ ຕົວແປ. ທ່ານສາມາດກຳນົດຕົວແປທີ່ຖືກປະກາດດ້ວຍ let ຄືນໃໝ່, ສະນັ້ນເລີ່ມຈາກການໃຫ້ຄ່າເລີ່ມຕົ້ນເນື້ອຫາທີ່ທ່ານຕ້ອງການສະແດງ, ຊື່:

let itemContent = name;

ນຳໃຊ້ if statement ເພື່ອກຳນົດຄ່າ JSX expression ຄືນໃໝ່ໃຫ້ itemContent ຖ້າ isPacked ເປັນ true:

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

ວົງປີກກາ “ໜ້າຕ່າງເຂົ້າສູ່ JavaScript”. Embed ຕົວແປດ້ວຍວົງປີກກາໃນການ return JSX tree, ຊ້ອນ expression ທີ່ຄຳນວນໄວ້ກ່ອນໜ້ານີ້ພາຍໃນ JSX:

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

ແບບນີ້ມີລາຍລະອຽດຫຼາຍທີ່ສຸດ, ແຕ່ກໍຍືດຍຸ່ນທີ່ສຸດເຊັ່ນກັນ. ນີ້ແມ່ນວິທີການ:

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

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

ຄືກັບຜ່ານມາ, ນີ້ບໍ່ສະເພາະເຮັດວຽກໄດ້ນຳຂໍ້ຄວາມ, ແຕ່ສຳລັບ arbitrary JSX ກໍໄດ້ເຊັ່ນກັນ!

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>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}

ຖ້າທ່ານຍັງບໍ່ຄຸ້ນເຄີຍກັບ JavaScript, ຮູບແບບນີ້ອາດເບິ່ງຄືຫຼາຍໃນຕອນທຳອິດ. ເຖິງຢ່າງໃດກໍ່ຕາມ, ການຮຽນຮູ້ສິ່ງເຫຼົ່ານີ້ຈະຊ່ວຍໃຫ້ທ່ານອ່ານ ແລະ ຂຽນ code JavaScript ໃດກໍໄດ້ — ແລະ ບໍ່ສະເພາະແຕ່ component React! ເລືອກອັນໜຶ່ງທີ່ທ່ານມັກສຳລັບເລີ່ມຕົ້ນ, ແລະ ເບິ່ງຂໍ້ມູນອ້າງອີງນີ້ອີກຄັ້ງຖ້າທ່ານລືມວິທິການທີ່ຮູບແບບອື່ນເຮັດ.

Recap

  • ໃນ React, ທ່ານສາມາດຄວບຄຸມ branching logic ດ້ວຍ JavaScript.
  • ທ່ານສາມາດ return JSX expression ແບບມີເງື່ອນໄຂດ້ວຍ if statement.
  • ທ່ານສາມາດບັນທຶກບາງ JSX ໃສ່ຕົວແປຢ່າງມີເງື່ອນໄຂ ແລະ ລວມມັນພາຍໃນ JSX ອື່ນດ້ວຍການໃຊ້ວົງປີກກາ.
  • ໃນ JSX, {cond ? <A /> : <B />} ໝາຍຄວາມວ່າ “ຖ້າ cond, ສະແດງຜົນ <A />, ນອກນັ້ນ <B />.
  • ໃນ JSX, {cond && <A />} ໝາຍຄວາມວ່າ “if cond, ສະແດງຜົນ <A />, ນອກນັ້ນບໍ່ສະແດງຫຍັງ”.
  • ທາງລັດເປັນເລື່ອງປົກະຕິ, ແຕ່ທ່ານບໍ່ຈຳເປັນຕ້ອງໃຊ້ຫາກຕ້ອງການໃຊ້ if ທຳມະດາ.

Challenge 1 of 3:
ສະແດງໄອຄອນສຳລັບລາຍການທີ່ບໍ່ສົມບູນດ້ວຍ ? :

ນຳໃຊ້ conditional operator (cond ? a : b) ເພື່ອສະແດງຜົນ ❌ ຖ້າ isPacked ບໍ່ເປັນ true.

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

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item 
          isPacked={true} 
          name="Space suit" 
        />
        <Item 
          isPacked={true} 
          name="Helmet with a golden leaf" 
        />
        <Item 
          isPacked={false} 
          name="Photo of Tam" 
        />
      </ul>
    </section>
  );
}