Komponen Senyawa Dalam Bereaksi
Diterbitkan: 2022-03-10Komponen gabungan membantu pengembang membangun API yang lebih ekspresif dan fleksibel untuk berbagi status dan logika di dalam komponen. Tutorial ini menjelaskan bagaimana hal ini dapat dicapai dengan bantuan penggunaan Context API dan React untuk membangun komponen dengan menggunakan pola lanjutan ini.
Catatan : Agar dapat mengikuti, Anda memerlukan pemahaman dasar tentang React dan cara kerja Context API.
Apa Itu Komponen Senyawa?
Komponen gabungan dapat dikatakan sebagai pola yang melingkupi keadaan dan perilaku sekelompok komponen tetapi masih memberikan kontrol rendering bagian variabelnya kembali ke pengguna eksternal.
Dari definisi di atas, perhatikan kata kunci: state and behavior . Ini membantu kita memahami bahwa komponen majemuk berhubungan dengan keadaan (yaitu bagaimana keadaan berperilaku di seluruh komponen yang diapit oleh pengguna eksternal yang menjadi induk dari komponen).
Tujuan dari komponen gabungan adalah untuk menyediakan API yang lebih ekspresif dan fleksibel untuk komunikasi antara komponen induk dan anak.
Anggap saja seperti <select>
dan <option>
dalam HTML:
<select> <option value="volvo">Volvo</option> <option value="mercedes">Mercedes</option> <option value="audi">Audi</option> </select>
Tag select
bekerja bersama dengan tag option
yang digunakan untuk menu tarik-turun untuk memilih item dalam HTML. Di sini <select>
mengelola status UI, lalu elemen <option>
dikonfigurasi tentang cara kerja <select>
. Komponen gabungan di React digunakan untuk membangun komponen UI deklaratif yang membantu menghindari pengeboran penyangga.
Pengeboran prop melewati props ke beberapa komponen anak. Ini juga yang mereka sebut "bau kode". Bagian terburuk dari prop drilling adalah ketika komponen induk dirender ulang, komponen turunan juga akan dirender ulang dan menyebabkan efek domino pada komponen. Solusi yang baik adalah dengan menggunakan React Context API yang juga akan kita lihat nanti.
Menerapkan Komponen Senyawa Dalam Bereaksi
Bagian ini menjelaskan paket yang dapat kita gunakan dalam aplikasi kita yang mengadopsi pola komponen gabungan dari komponen bangunan di React. Contoh ini adalah komponen Menu
dari paket UI @reach
.
import { Menu, MenuList, MenuButton, MenuItem, MenuItems, MenuPopover, MenuLink, } from "@reach/menu-button"; import "@reach/menu-button/styles.css";
Berikut adalah cara Anda dapat menggunakan komponen Menu
:
function Example() { return ( <Menu> <MenuButton>Actions</MenuButton> <MenuList> <MenuItem>Download</MenuItem> <MenuLink to="view">View</MenuLink> </MenuList> </Menu> ); }
Contoh kode di atas adalah salah satu implementasi komponen gabungan di mana Anda dapat melihat bahwa Menu
, MenuButton
, MenuList
, MenuItem
dan MenuLink
semuanya diimpor dari @reach/menu-button
. Berbeda dengan mengekspor satu komponen, ReachUI mengekspor komponen induk yaitu Menu
yang menyertai komponen turunannya yaitu MenuButton
, MenuList
, MenuItem
dan MenuLink
.
Kapan Anda Harus Menggunakan Komponen Senyawa?
Sebagai pengembang React, Anda harus menggunakan komponen compound ketika Anda ingin:
- Memecahkan masalah yang terkait dengan membangun komponen yang dapat digunakan kembali;
- Pengembangan komponen yang sangat kohesif dengan kopling minimal;
- Cara yang lebih baik untuk berbagi logika antar komponen.
Pro Dan Kontra Komponen Senyawa
Komponen gabungan adalah pola React yang luar biasa untuk ditambahkan ke toolkit pengembang React Anda. Di bagian ini, saya akan menyatakan pro dan kontra menggunakan komponen majemuk dan apa yang telah saya pelajari dari membangun komponen menggunakan pola pengembangan ini.
kelebihan
Pemisahan Kekhawatiran
Memiliki semua logika status UI di komponen induk dan mengomunikasikannya secara internal ke semua komponen turunan membuat pembagian tanggung jawab yang jelas.Mengurangi Kompleksitas
Berbeda dengan pengeboran prop untuk menurunkan properti ke komponen spesifiknya, child props pergi ke komponen turunannya masing-masing menggunakan pola komponen majemuk.
Kontra
Salah satu kelemahan utama dari membangun komponen di React dengan pola komponen majemuk adalah bahwa hanya direct children
dari komponen induk yang memiliki akses ke props, yang berarti kita tidak dapat membungkus komponen ini dalam komponen lain.
export default function FlyoutMenu() { return ( <FlyOut> {/* This breaks */} <div> <FlyOut.Toggle /> <FlyOut.List> <FlyOut.Item>Edit</FlyOut.Item> <FlyOut.Item>Delete</FlyOut.Item> </FlyOut.List> </div> </FlyOut> ); }
Solusi untuk masalah ini adalah dengan menggunakan pola komponen gabungan fleksibel untuk berbagi status secara implisit menggunakan React.createContext
API.
Context API memungkinkan untuk meneruskan status React melalui komponen bersarang saat membangun menggunakan pola komponen gabungan dari komponen bangunan di React. Ini dimungkinkan karena context
menyediakan cara untuk meneruskan data ke pohon komponen tanpa harus menurunkan props secara manual di setiap level. Memanfaatkan API Konteks memberikan banyak fleksibilitas kepada pengguna akhir.
Mempertahankan Komponen Senyawa Dalam Bereaksi
Komponen gabungan menyediakan cara yang lebih fleksibel untuk berbagi status dalam aplikasi React, sehingga penggunaan komponen gabungan dalam aplikasi React Anda mempermudah pemeliharaan dan benar-benar men-debug aplikasi Anda.
Membangun Demo
Pada artikel ini, kita akan membuat komponen akordeon di React menggunakan pola komponen majemuk. Komponen yang akan kita buat dalam tutorial ini adalah komponen akordeon yang dibuat khusus yang fleksibel dan berbagi status di dalam komponen dengan menggunakan API Konteks.
Ayo pergi!
Pertama-tama, mari kita buat aplikasi React dengan menggunakan yang berikut ini:
npx create-react-app accordionComponent cd accordionComponent npm start
atau
yarn create react-app accordionComponent cd accordionComponent yarn start
Perintah di atas membuat aplikasi React, mengubah direktori ke proyek React, dan memulai server pengembangan.
Catatan : Dalam tutorial ini, kita akan menggunakan styled-components
untuk membantu menata komponen kita.
Gunakan perintah di bawah ini untuk menginstal styled-components
:
yarn add styled-components
atau
npm install --save styled-components
Di folder src , buat folder baru bernama component . Di sinilah semua komponen kita akan hidup. Di dalam folder komponen , buat dua file baru: accordion.js
dan accordion.styles.js
.
File accordion.styles.js
berisi penataan gaya untuk komponen Accordion
(penataan gaya dilakukan menggunakan styled-components
).
import styled from "styled-components"; export const Container = styled.div` display: flex; border-bottom: 8px solid #222; `;
Di atas adalah contoh komponen styling menggunakan library css-in-js
yang disebut styled-components
.
Di dalam file accordion.styles.js
, tambahkan gaya yang tersisa:
export const Frame = styled.div` margin-bottom: 40px; `; export const Inner = styled.div` display: flex; padding: 70px 45px; flex-direction: column; max-width: 815px; margin: auto; `; export const Title = styled.h1` font-size: 40px; line-height: 1.1; margin-top: 0; margin-bottom: 8px; color: black; text-align: center; `; export const Item = styled.div` color: white; margin: auto; margin-bottom: 10px; max-width: 728px; width: 100%; &:first-of-type { margin-top: 3em; } &:last-of-type { margin-bottom: 0; } `; export const Header = styled.div` display: flex; flex-direction: space-between; cursor: pointer; margin-bottom: 1px; font-size: 26px; font-weight: normal; background: #303030; padding: 0.8em 1.2em 0.8em 1.2em; user-select: none; align-items: center; img { filter: brightness(0) invert(1); width: 24px; user-select: none; @media (max-width: 600px) { width: 16px; } } `; export const Body = styled.div` font-size: 26px; font-weight: normal; line-height: normal; background: #303030; white-space: pre-wrap; user-select: none; overflow: hidden; &.closed { max-height: 0; overflow: hidden; transition: max-height 0.25ms cubic-bezier(0.5, 0, 0.1, 1); } &.open { max-height: 0px; transition: max-height 0.25ms cubic-bezier(0.5, 0, 0.1, 1); } span { display: block; padding: 0.8em 2.2em 0.8em 1.2em; } `;
Mari kita mulai membangun komponen akordeon kita. Pada file accordion.js
, mari tambahkan kode berikut:
import React, { useState, useContext, createContext } from "react"; import { Container, Inner, Item, Body, Frame, Title, Header } from "./accordion.styles";
Di atas, kita mengimpor useState
, useContext
dan createContext
yang akan membantu kita membangun komponen akordeon menggunakan komponen majemuk.
Dokumentasi React menjelaskan bahwa context
membantu menyediakan cara untuk melewatkan data melalui pohon komponen tanpa harus menurunkan props secara manual di setiap level.
Melihat apa yang telah kami impor sebelumnya di file accordion.js
kami, Anda akan melihat bahwa kami juga mengimpor gaya kami sebagai komponen yang akan membantu kami membangun komponen kami lebih cepat.
Kami akan melanjutkan dan membuat konteks kami untuk komponen yang akan berbagi data dengan komponen yang membutuhkannya:
const ToggleContext = createContext(); export default function Accordion({ children, ...restProps }) { return ( <Container {...restProps}> <Inner>{children}</Inner> </Container> ); }
Komponen Container
dan Inner
dari cuplikan kode di atas berasal dari file ./accordion.styles.js
tempat kami membuat gaya untuk komponen menggunakan komponen styled-components
(dari pustaka css-in-js
). Komponen Container
menampung seluruh Accordion
yang kami buat dengan menggunakan komponen majemuk.
Di sini kita membuat objek konteks menggunakan metode createContext()
, jadi ketika React merender komponen yang berlangganan ke objek Context ini, ia akan membaca nilai konteks saat ini dari Penyedia terdekat yang cocok di atasnya di pohon.
Kemudian kami juga membuat komponen dasar kami yaitu Accordion; dibutuhkan anak- children
dan restProps
apapun. Ini adalah komponen induk kami yang menampung komponen anak-anak dari Accordion.
Mari buat komponen turunan lainnya di dalam file accordion.js
:
Accordion.Title = function AccordionTitle({ children, ...restProps }) { return <Title {...restProps}>{children}</Title>; }; Accordion.Frame = function AccordionFrame({ children, ...restProps }) { return <Frame {...restProps}>{children}</Frame>; };
Perhatikan .
setelah komponen Accordion induk; ini digunakan untuk menghubungkan komponen anak ke komponen induknya.
Ayo lanjutkan. Sekarang tambahkan yang berikut ke file accordion.js
:
Accordion.Item = function AccordionItem({ children, ...restProps }) { const [toggleShow, setToggleShow] = useState(true); return ( <ToggleContext.Provider value={{ toggleShow, setToggleShow }}> <Item {...restProps}>{children}</Item> </ToggleContext.Provider> ); }; Accordion.ItemHeader = function AccordionHeader({ children, ...restProps }) { const { isShown, toggleIsShown } = useContext(ToggleContext); return ( <Header onClick={() => toggleIsShown(!isShown)} {...restProps}> {children} </Header> ); }; Accordion.Body = function AccordionHeader({ children, ...restProps }) { const { isShown } = useContext(ToggleContext); return ( <Body className={isShown ? "open" : "close"}> <span>{children}</span> </Body> ); };
Jadi di sini kita membuat komponen Body
, Header
dan Item
yang semuanya merupakan anak dari komponen induk Accordion
. Di sinilah mungkin mulai menjadi rumit. Juga, perhatikan bahwa setiap komponen anak yang dibuat di sini juga menerima children
prop dan restprops
.
Dari komponen anak Item
, kami menginisialisasi status kami menggunakan kait useState
dan menyetelnya menjadi benar. Kemudian ingat juga bahwa kita membuat ToggleContext
di tingkat atas dari file accordion.js
yang merupakan Context Object
, dan ketika React merender komponen yang berlangganan ke objek Context ini, ia akan membaca nilai konteks saat ini dari Penyedia terdekat yang cocok di atasnya Di pohon.
Setiap objek Context dilengkapi dengan komponen Provider
React yang memungkinkan komponen yang mengkonsumsi untuk berlangganan perubahan konteks.
Komponen provider
menerima prop value
untuk diteruskan ke komponen konsumsi yang merupakan turunan dari penyedia ini, dan di sini kita meneruskan nilai status saat ini yang merupakan toggleShow
dan metode untuk menyetel nilai status saat ini setToggleShow
. Mereka adalah nilai yang menentukan bagaimana objek konteks kita akan berbagi status di sekitar komponen kita tanpa pengeboran penyangga.
Kemudian di komponen anak header
dari Accordion
, kami merusak nilai objek konteks, lalu mengubah status toggleShow
saat diklik. Jadi yang kami coba lakukan adalah menyembunyikan atau menampilkan akordeon kami saat Header diklik.
Dalam komponen Accordion.Body
kami, kami juga menghancurkan toggleShow
yang merupakan status komponen saat ini, kemudian tergantung pada nilai toggleShow
, kami dapat menyembunyikan body atau menampilkan konten komponen Accordion.Body
.
Jadi itu saja untuk file accordion.js
kami.
Sekarang di sinilah kita bisa melihat bagaimana semua yang telah kita pelajari tentang komponen Context
dan Compound components
bersatu. Tapi sebelum itu, mari buat file baru bernama data.json
dan paste konten di bawah ini ke dalamnya:
[ { "id": 1, "header": "What is Netflix?", "body": "Netflix is a streaming service that offers a wide variety of award-winning TV programs, films, anime, documentaries and more – on thousands of internet-connected devices.\n\nYou can watch as much as you want, whenever you want, without a single advert – all for one low monthly price. There's always something new to discover, and new TV programs and films are added every week!" }, { "id": 2, "header": "How much does Netflix cost?", "body": "Watch Netflix on your smartphone, tablet, smart TV, laptop or streaming device, all for one low fixed monthly fee. Plans start from £5.99 a month. No extra costs or contracts." }, { "id": 3, "header": "Where can I watch?", "body": "Watch anywhere, anytime, on an unlimited number of devices. Sign in with your Netflix account to watch instantly on the web at netflix.com from your personal computer or on any internet-connected device that offers the Netflix app, including smart TVs, smartphones, tablets, streaming media players and game consoles.\n\nYou can also download your favorite programs with the iOS, Android, or Windows 10 app. Use downloads to watch while you're on the go and without an internet connection. Take Netflix with you anywhere." }, { "id": 4, "header": "How do I cancel?", "body": "Netflix is flexible. There are no annoying contracts and no commitments. You can easily cancel your account online with two clicks. There are no cancellation fees – start or stop your account at any time." }, { "id": 5, "header": "What can I watch on Netflix?", "body": "Netflix has an extensive library of feature films, documentaries, TV programs, anime, award-winning Netflix originals, and more. Watch as much as you want, any time you want." } ]
Ini adalah data yang akan kami kerjakan untuk menguji komponen akordeon kami.
Jadi mari kita lanjutkan. Kami hampir selesai dan saya yakin Anda telah belajar banyak dari mengikuti artikel ini.
Di bagian ini, kita akan menyatukan semua yang telah kita kerjakan dan pelajari tentang komponen gabungan untuk dapat menggunakannya di file App.js
kita untuk menggunakan fungsi Array.map
untuk menampilkan data yang sudah kita miliki di web halaman. Perhatikan juga bahwa tidak ada penggunaan status dalam App.js
; yang kami lakukan hanyalah meneruskan data ke komponen tertentu dan API Konteks menangani semua hal lainnya.
Sekarang ke bagian terakhir. Di App.js
Anda, lakukan hal berikut:
import React from "react"; import Accordion from "./components/Accordion"; import faqData from "./data"; export default function App() { return ( <Accordion> <Accordion.Title>Frequently Asked Questions</Accordion.Title> <Accordion.Frame> {faqData.map((item) => ( <Accordion.Item key={item.id}> <Accordion.Header>{item.header}</Accordion.Header> <Accordion.Body>{item.body}</Accordion.Body> </Accordion.Item> ))} </Accordion.Frame> </Accordion> ); }
Di file App.js Anda, kami mengimpor Compound Component Accordion kami dari jalur file, kemudian juga mengimpor data dummy kami, dipetakan melalui data dummy untuk mendapatkan item individual dalam file data kami, lalu menampilkannya sesuai dengan masing-masing komponen, Anda juga akan melihat bahwa yang harus kami lakukan hanyalah meneruskan anak-anak ke komponen masing-masing, API Konteks memastikan bahwa itu mencapai komponen yang tepat dan tidak ada pengeboran penyangga.
Seperti inilah seharusnya produk akhir kita:
Alternatif Untuk Komponen Senyawa
Alternatif untuk menggunakan komponen majemuk adalah dengan menggunakan Render Props API. Istilah Render Prop di React mengacu pada teknik untuk berbagi kode antara komponen React menggunakan prop yang nilainya adalah fungsi. Sebuah komponen dengan prop render mengambil fungsi yang mengembalikan elemen React dan memanggilnya alih-alih mengimplementasikan logika rendernya sendiri.
Untuk meneruskan data dari komponen ke komponen turunan yang memerlukan data dapat mengakibatkan pengeboran penyangga saat Anda memiliki komponen yang bersarang di dalam satu sama lain. Ini adalah keuntungan menggunakan Konteks untuk berbagi data antar komponen daripada menggunakan metode prop render.
Kesimpulan
Pada artikel ini, kita mempelajari salah satu pola lanjutan dari React yang merupakan pola komponen majemuk. Ini adalah metode yang luar biasa untuk membangun komponen yang dapat digunakan kembali di Bereaksi dengan menggunakan pola komponen majemuk untuk membangun komponen Anda menawarkan banyak fleksibilitas dalam komponen Anda. Anda masih dapat memilih untuk menggunakan Render Prop jika fleksibilitas tidak dibutuhkan oleh komponen Anda saat ini.
Komponen majemuk paling membantu dalam membangun sistem desain. Kami juga melalui proses berbagi status dalam komponen menggunakan API Konteks.
- Kode untuk tutorial ini dapat ditemukan di Codesandbox.