ການສົ່ງ Props ໄປຫາ Component
Component React ໃຊ້ props ເພື່ອສື່ສານລະຫວ່າງກັນ ແລະ ກັນ. ທຸກໆ parent component ສາມາດສົ່ງບາງຂໍ້ມູນໄປຫາ child component ມັນເອງໂດຍການໃຫ້ props. Props ອາດເຕືອນທ່ານກ່ຽວກັບ attribute HTML, ແຕ່ທ່ານສາມາດສົ່ງຄ່າຂອງ JavaScript ໃດກໍໄດ້ຜ່ານມັນລວມເຖິງ objects, arrays, ແລະ ຟັງຊັ່ນ.
You will learn
- ວິທີສົ່ງ props ໄປຫາ component
- ວິທີອ່ານ props ຈາກ component
- ວິທີກຳນົດຄ່າເລີ່ມຕົ້ນສຳລັບ props
- ວິທີສົ່ງບາງ JSX ໄປຫາ component
- ວິທີທີ່ props ປ່ຽນແປງຕະຫຼອດເວລາ
ຄຸ້ນເຄີຍກັບ props
Props ແມ່ນຂໍ້ມູນທີ່ທ່ານສົ່ງຜ່ານແທັກ JSX. ຕົວຢ່າງ, className
, src
, alt
, width
, ແລະ height
ແມ່ນບາງ props ທີ່ທ່ານສາມາດສົ່ງຜ່ານ <img>
:
function Avatar() { return ( <img className="avatar" src="https://i.imgur.com/1bX5QH6.jpg" alt="Lin Lanying" width={100} height={100} /> ); } export default function Profile() { return ( <Avatar /> ); }
Props ສາມາດສົ່ງຜ່ານແທັກ <img>
ນັ້ນຖືກກຳນົດແລ້ວ (ReactDOM conforms to the HTML standard). ແຕ່ທ່ານສາມາດສົ່ງ props ໃດກໍ່ໄດ້ໄປຫາ component ຂອງທ່ານເອງ, ເຊັ່ນ <Avatar>
, ເພື່ອປັບແຕ່ງ. ນີ້ແມ່ນວິທີ!
ການສົ່ງ props ໄປຫາ component
ໃນ code ນີ້, Component Profile
ບໍ່ສາມາດສົ່ງ props ໃດກໍໄດ້ໄປຫາ child component, Avatar
:
export default function Profile() {
return (
<Avatar />
);
}
ທ່ານສາມາດໃຫ້ props Avatar
ໃນສອງຂັ້ນຕອນ.
ຂັ້ນຕອນທີ 1: ສົ່ງ props ໄປຫາ child component
ທຳອິດ, ສົ່ງ props ໄປຫາ Avatar
. ຕົວຢ່າງ, ສົ່ງ 2 props: person
(ເປັນ object), ແລະ size
(ເປັນ number):
export default function Profile() {
return (
<Avatar
person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }}
size={100}
/>
);
}
ທ່ານສາມາດອ່ານ props ນີ້ພາຍໃນ component Avatar
ຂັ້ນຕອນທີ 2: ການອ່ານ props ພາຍໃນ child component
ທ່ານສາມາດອ່ານ props ໂດຍລະບຸຊື່ person, size
ແຍກກັນໂດຍໃສ່ເຄື່ອງໝາຍຈຸດພາຍໃນ ({
ແລະ })
ໂດຍກົງຫຼັງຈາກ function Avatar
. ນີ້ເຮັດໃຫ້ທ່ານສາມາດນຳໃຊ້ພາຍໃນ code Avatar
, ຄືກັບທີທ່ານໃຊ້ກັບຕົວແປ.
function Avatar({ person, size }) {
// person and size are available here
}
ເພີ່ມ logic ໃສ່ Avatar
ທີ່ໃຊ້ props person
ແລະ size
ສຳລັບການສະແດງຜົນເທົ່ານີ້ກໍສຳເລັດ.
ຕອນນີ້ທ່ານສາມາດຕັ້ງຄ່າ Avatar
ເພື່ອສະແດງໄດ້ຫຼາຍວິທີດ້ວຍຫຼາຍ prop ທີ່ແຕກຕ່າງກັນ. ລອງປັບຫຼິ້ນເບິ່ງ!
import { getImageUrl } from './utils.js'; function Avatar({ person, size }) { return ( <img className="avatar" src={getImageUrl(person)} alt={person.name} width={size} height={size} /> ); } export default function Profile() { return ( <div> <Avatar size={100} person={{ name: 'Katsuko Saruhashi', imageId: 'YfeOqp2' }} /> <Avatar size={80} person={{ name: 'Aklilu Lemma', imageId: 'OKS67lh' }} /> <Avatar size={50} person={{ name: 'Lin Lanying', imageId: '1bX5QH6' }} /> </div> ); }
Props ເຮັດໃຫ້ທ່ານຄິດກ່ຽວກັບ parent ແລະ child component ຢ່າງອິດສະຫຼະ. ຕົວຢ່າງ, ທ່ານສາມາດປ່ຽນ prop person
ຫຼື size
ພາຍໃນ Profile
ໂດຍບໍ່ຈຳເປັນຕ້ອງຄິດວ່າ Avatar
ໃຊ້ສິ່ງນີ້ແນວໃດ. ຄ້າຍຄືກັນ, ທ່ານສາມາດປ່ຽນວິທີທີ່ Avatar
ໃຊ້ props, ໂດຍບໍ່ຕ້ອງເບິ່ງທີ່ Profile
.
ທ່ານສາມາດຄິດວ່າ props ຄືກັບລູກບິດທີ່ທ່ານສາມາດປັບໄດ້. ມັນເຮັດໜ້າທີ່ເປັນ argument ທີ່ເຮັດວຽກສຳລັບຟັງຊັ່ນ-ຄວາມຈິງ, props ເປັນ argument ດຽວສຳລັບ component ຂອງທ່ານ! ຟັງຊັ່ນ component React ຮັບ argument ດຽວ, props
object:
function Avatar(props) {
let person = props.person;
let size = props.size;
// ...
}
ປົກະຕິແລ້ວທ່ານບໍ່ຈຳເປັນຕ້ອງໃຊ້ props
object ທັງໝົດ, ສະນັ້ນ ທ່ານສາມາດແຕກມັນອອກເປັນ props ຍ່ອຍແຕ່ລະອັນ.
ການລະບຸຄ່າເລີ່ມຕົ້ນສຳລັບ prop
ຫາກທ່ານຕ້ອງການໃຫ້ຄ່າ prop ເລີ່ມຕົ້ນເພື່ອໃຊ້ແທນເມື່ອບໍ່ໄດ້ລະບຸຄ່າໄວ້, ທ່ານສາມາດເຮັດໄດ້ໂດຍການ destructuring ໂດຍໃສ່ =
ແລະ ຄ່າເລີ່ມຕົ້ນໄວ້ຫຼັງ parameter:
function Avatar({ person, size = 100 }) {
// ...
}
ຕອນນີ້, ຖ້າ <Avatar person={...} />
ສະແດງໂດຍບໍ່ມີ prop size
, size
ຈະຖືກຕັ້ງຄ່າເປັນ 100
.
ຄ່າເລີ່ມຕົ້ນຈະຖືກໃຊ້ກໍຕໍ່ເມືອບໍ່ມີ prop size
ຫຼື ຖ້າທ່ານສົ່ງ size={undefined}
. ແຕ່ຖ້າທ່ານສົ່ງ size={null}
ຫຼື size={0}
, ຄ່າເລີ່ມຕົ້ນຈະ ບໍ່ຖືກ ໃຊ້.
ການສົ່ງຕໍ່ props ດ້ວຍ spread syntax JSX
ບາງເທື່ອ, ການສົ່ງ props ແມ່ນຊໍ້າກັນຫຼາຍ:
function Profile({ person, size, isSepia, thickBorder }) {
return (
<div className="card">
<Avatar
person={person}
size={size}
isSepia={isSepia}
thickBorder={thickBorder}
/>
</div>
);
}
ມັນບໍ່ມີຫຍັງຜິດຖ້າ code ຊໍ້າ-ມັນສາມາດອ່ານໄດ້ຊັດເຈນຂຶ້ນ. ແຕ່ບາງຄັ້ງທ່ານອາດໃຫ້ຄວາມສຳຄັນກັບຄວາມກະທັດຮັດ. ບາງ component ສົ່ງຜ່ານ props ທັງໝົດໄປຫາ children ຂອງມັນທັງໝົດ, ເຊັ່ນດຽວກັບວິທີ Profile
ນີ້ເຮັດກັບ Avatar
. ເພາະວ່າພວກມັນບໍ່ໃຊ້ prop ໂດຍກົງ, ຈຶ່ງເໝາະສົມທີ່ຈະໃຊ້ syntax “spread” ທີກະທັດຮັດກວ່ານີ້:
function Profile(props) {
return (
<div className="card">
<Avatar {...props} />
</div>
);
}
ນີ້ສົ່ງຕໍ່ prop ທັງໝົດຂອງ Profile
ໄປຫາ Avatar
ໂດຍບໍ່ລະບຸຊື່ແຕ່ລະລາຍການ.
ໃຊ້ spread syntax ດ້ວຍຄວາມລະມັດລະວັງ. ຖ້າທ່ານໃຊ້ມັນທຸກໆ component ອື່ນ, ສະແດງວ່າມີບາງຢ່າງຜິດປົກະຕິ. ສ່ວນຫຼາຍ, ມັນບົ່ງບອກວ່າທ່ານຄວນຈະແຍກ component ແລະ ສົ່ງ children ເປັນ JSX. ເພີ່ມເຕີມຕໍ່ໄປ!
ການສົ່ງ JSX ເປັນ children
ມັນເປັນເລື່ອງປົກະຕິທີ່ຈະຊ້ອນ built-in ແທັກບາວເຊີ:
<div>
<img />
</div>
ບາງເທື່ອທ່ານຕ້ອງການຊ້ອນ component ຂອງທ່ານດ້ວຍຮູບແບບດຽວກັນ:
<Card>
<Avatar />
</Card>
ເມື່ອທ່ານຊ້ອນເນື້ອຫາພາຍໃນແທັກ JSX, parent component ຈະຮັບເນື້ອຫາໃນ prop ເອີ້ນວ່າ children
. ຕົວຢ່າງ, component Card
ດ້ານລຸ່ມຈະຮັບ prop children
ຕັ້ງຄ່າໃຫ້ <Avatar />
ແລະ ສະແດງຜົນທາງໃນ div ທີ່ຄອບ:
import Avatar from './Avatar.js'; function Card({ children }) { return ( <div className="card"> {children} </div> ); } export default function Profile() { return ( <Card> <Avatar size={100} person={{ name: 'Katsuko Saruhashi', imageId: 'YfeOqp2' }} /> </Card> ); }
ລອງແທນທີ່ <Avatar>
ພາຍໃນ <Card>
ດ້ວຍຂໍ້ຄວາມເພື່ອເບິ່ງວ່າ component Card
ສາມາດຄອບເນື້ອຫາທີ່ຊ້ອນກັນ. ມັນບໍ່ຈຳເປັນຕ້ອງ “ຮູ້” ສິ່ງທີ່ກຳລັງສະແດງພາຍໃນມັນ. ທ່ານຈະເຫັນຮູບແບບທີ່ຢືດຫຍຸ່ນນີ້ຫຼາຍບ່ອນ.
ທ່ານສາມາດຄິດວ່າ component ທີ່ມີ prop children
ວ່າມີ “ຂຸມ” ທີ່ສາມາດ “ເຕິມລົງ” ໂດຍ parent component ດ້ວຍ JSX ຕາມໃຈ. ທ່ານຈະໄດ້ໃຊ້ prop children
ເລື້ອຍໆສຳລັບການຫໍ່ຫຸ້ມພາບເຊັ່ນ: panels, grids, ແລະ ອື່ນໆ.
Illustrated by Rachel Lee Nabors
props ປ່ຽນແປງແນວໃດເມື່ອເວລາຜ່ານໄປ
Component Clock
ດ້ານລຸ່ມຈະໄດ້ຮັບສອງ prop ຈາກ parent component ມັນເອງ: color
ແລະ time
. (Code ຂອງ parent component ແມ່ນຖືກປະໄວ້ເພາະວ່າມັນໃຊ້state, ທີ່ພວກເຮົາຍັງບໍ່ທັນເຈາະລົງເລິກໄປຕື່ມເທື່ອ.)
ລອງປ່ຽນສີໃນ select box ດ້ານລຸ່ມ:
export default function Clock({ color, time }) { return ( <h1 style={{ color: color }}> {time} </h1> ); }
ໃນຕົວຢ່າງນີ້ສະແດງໃຫ້ເຫັນວ່າ component ອາດໄດ້ຮັບ prop ທີ່ແຕກຕ່າງເມື່ອເວລາຜ່ານໄປ. Props ບໍ່ເປັນ static ສະເໝີໄປ! ນີ້, prop time
ປ່ຽນແປງທຸກວິນາທີ, ແລະ prop color
ປ່ຽນເມື່ອທ່ານເລືອກສີອື່ນ. Prop ສະທ້ອນຂໍ້ມູນ component ໃນເວລາໃດໜຶ່ງ, ແທນທີ່ຈະສະແດງສະເພາະໃນຊ່ວງເລີ່ມຕົ້ນ.
ເຖິງຢ່າງໃດກໍຕາມ, props ແມ່ນ immutable—ຄຳສັບຈາກວິທະຍາສາດຄອມພິວເຕີມີຄວາມໝາຍວ່າ “ບໍ່ປ່ຽນແປງ”. ເມື່ອ component ຕ້ອງການປ່ຽນແປງ prop ມັນເອງ (ຍົກຕົວຢ່າງ, ໃນຕອນ response ຫາການໂຕ້ຕອບຜູ້ໃຊ້ ຫຼື ຂໍ້ມູນໃໝ່), ມັນຕ້ອງໄດ້ “ຂໍ” parent component ຂອງມັນເອງເພື່ອສົ່ງ prop ທີ່ແຕກຕ່າງ—object ໃໝ່! prop ເກົ່າຈະຖືກຖີ້ມ ແລະ ໃນທີ່ສຸດ JavaScript engine ຈະເອີ້ນຄືນ memory ທີ່ພວກມັນເອົາໄປ.
ຢ່າພາຍາຍາມ “ປ່ຽນ props”. ເມື່ອທ່ານຕ້ອງການ respond ຄືນຫາ user input (ເຊັ່ນ ປ່ຽນສີທີ່ເລືອກ), ທ່ານຈະຕ້ອງການ “set state”, ທີ່ທ່ານໄດ້ຮຽນກ່ຽວກັບ State: A Component’s Memory.
Recap
- ຫາກຕ້ອງການສົ່ງ props, ໃຫ້ເພີ່ມລົງໃນ JSX, ເຊັ່ນດຽວກັບທີ່ທ່ານເຮັດກັບ attribute HTML.
- ຫາກຕ້ອງການອ່ານ props, ໃຊ້ destructuring syntax
function Avatar({ person, size})
. - ທ່ານສາມາດກຳນົດຄ່າເລີ່ມຕົ້ນເຊັ່ນ
size = 100
, ເຊິ່ງໃຊ້ສຳລັບ props ທີ່ບໍ່ມີ ຫຼື ເປັນundefined
. - ທ່ານສາມາດສົ່ງຕໍ່ທຸກ props ດ້ວຍ JSX spread syntax
<Avatar {...props} />
, ແຕ່ຢ່າໃຊ້ມັນຫຼາຍ! - JSX ທີ່ຊ້ອນກັນຫຼາຍເຊັ່ນ
<Card><Avatar /></Card>
ຈະປະກົດເປັນchildren
component ຂອງ componentCard
. - Props ແມ່ນ snapshot ທີ່ອ່ານໄດ້ຢ່າງດຽວໃນເວລາ: ທຸກໆການສະແດງຜົນຈະຮັບເວີຊັ່ນໃໝ່ຂອງ props.
- ທ່ານບໍ່ສາມາດປ່ຽນ props. ເມື່ອທ່ານຕ້ອງການ ການໂຕ້ຕອບ, ທ່ານຈະຕ້ອງຕັ້ງຄ່າ state.
Challenge 1 of 3: ແຕກ component
Component Gallery
ນີ້ມີ markup ທີ່ຄ້າຍກັນຫຼາຍສຳລັບສອງ profile. ແຕກ component Profile
ອອກມາເພື່ອຫຼຸດຄວາມຊໍ້າຊ້ອນ. ທ່ານຕ້ອງເລືອກ prop ທີ່ຈະສົ່ງໄປຫາມັນ.
import { getImageUrl } from './utils.js'; export default function Gallery() { return ( <div> <h1>Notable Scientists</h1> <section className="profile"> <h2>Maria Skłodowska-Curie</h2> <img className="avatar" src={getImageUrl('szV5sdG')} alt="Maria Skłodowska-Curie" width={70} height={70} /> <ul> <li> <b>Profession: </b> physicist and chemist </li> <li> <b>Awards: 4 </b> (Nobel Prize in Physics, Nobel Prize in Chemistry, Davy Medal, Matteucci Medal) </li> <li> <b>Discovered: </b> polonium (element) </li> </ul> </section> <section className="profile"> <h2>Katsuko Saruhashi</h2> <img className="avatar" src={getImageUrl('YfeOqp2')} alt="Katsuko Saruhashi" width={70} height={70} /> <ul> <li> <b>Profession: </b> geochemist </li> <li> <b>Awards: 2 </b> (Miyake Prize for geochemistry, Tanaka Prize) </li> <li> <b>Discovered: </b> a method for measuring carbon dioxide in seawater </li> </ul> </section> </div> ); }