React Bileşenleriniz İçin Yeniden Kullanılabilirliği Nasıl En Üst Düzeye Çıkarırsınız – JSManifest

React Bileşenleriniz İçin Yeniden Kullanılabilirliği Nasıl En Üst Düzeye Çıkarırsınız – JSManifest

React, geliştiricilerin web uygulamaları için son derece karmaşık ve etkileşimli kullanıcı arabirimleri oluşturmak için kullanabilecekleri popüler bir kitaplıktır. Bu kitaplığı uygulamalarını oluşturmak için kullanan birçok geliştirici, aynı zamanda birçok harika sebepler. Örneğin, bildirime dayalı doğası, web uygulamaları oluşturmayı daha az acı verici ve daha eğlenceli hale getirir, çünkü kod bizim elimizdeyken öngörülebilir ve daha kontrol edilebilir hale gelebilir.

Öyleyse, onu daha az acı verici yapan nedir ve tepkinin son derece karmaşık ve etkileşimli kullanıcı arayüzleri oluşturmak için nasıl kullanılabileceğini göstermeye yardımcı olabilecek bazı örnekler nelerdir?

Bu makale, tepki vermede yeniden kullanılabilirlik özelliklerini en üst düzeye çıkarmayı ele alacak ve bugün tepki uygulamanızda kullanabileceğiniz bazı ipuçları ve püf noktaları sağlayacaktır. Gerçek bir tepki bileşeni oluşturularak ve bazı adımların neden atıldığı ve bunlar üzerinde yeniden kullanılabilirliği geliştirmek için neler yapılabileceği adım adım açıklanarak gösterilecektir. Bir bileşeni yeniden kullanılabilir hale getirmenin birçok yolu olduğunu vurgulamak isterim ve bu gönderi bunu yapmanın önemli yollarını açıklayacak olsa da, yapar hepsini kapsamaz!

Bu gönderi yeni başlayanlar, orta ve ileri düzey tepki geliştiriciler içindir – ancak yeni başlayanlar ve orta düzey geliştiriciler için daha yararlı olacaktır.

Lafı fazla uzatmadan başlayalım!

Bileşen

hadi bir inşa edelim liste bileşen ve oradan yeteneklerini genişletmeye çalışın.

Kullanıcıların bir tıp uzmanları topluluğunun parçası olmak için kaydolduktan sonra yönlendirildikleri bir sayfa oluşturduğumuzu varsayın. Sayfa, yeni kayıtlı doktorların görüntüleyebileceği, doktorların oluşturabileceği grupların listelerini göstermelidir. Her liste bir tür başlık, açıklama, grubun yaratıcısı, grubunu temsil eden bir resim ve tarihler gibi bazı temel temel bilgileri göstermelidir.

Bunun gibi bir grubu temsil eden basit bir liste bileşeni oluşturabiliriz:

function List(props) {
  return (
    <div>
      <h5>
        Group: <em>Pediatricians</em>
      </h5>
      <ul>
        <p>Members</p>
        <li>Michael Lopez</li>
        <li>Sally Tran</li>
        <li>Brian Lu</li>
        <li>Troy Sakulbulwanthana</li>
        <li>Lisa Wellington</li>
      </ul>
    </div>
  )
}

O zaman kolayca render alabilir ve bir gün olarak adlandırabiliriz:

import React from 'react'
import List from './List'

function App() {
  return <List />
}

export default App

Açıkçası, bileşen yeniden kullanılabilir değil, bu nedenle bu sorunu, aksesuarlar aracılığıyla bazı temel yeniden kullanılabilirlik sağlayarak çözebiliriz. çocuklar:

function List(props) {
  return <div>{props.children}</div>
}
function App() {
  return (
    <List>
      <h5>
        Group: <em>Pediatricians</em>
      </h5>
      <ul>
        <p>Members</p>
        <li>Michael Lopez</li>
        <li>Sally Tran</li>
        <li>Brian Lu</li>
        <li>Troy Sakulbulwanthana</li>
        <li>Lisa Wellington</li>
      </ul>
    </List>
  )
}

Ama bu pek mantıklı değil, çünkü List bileşen artık bir liste bileşeni bile değil, hatta bir liste olarak adlandırılmamalıdır, çünkü şu anda bir div öğe. Kodu doğrudan içine de taşımış olabiliriz. App bileşen. Ama bu kötü çünkü artık sabit kodlanmış bileşene sahibiz. App. Listenin bir kerelik kullanım olduğundan eminsek, bu sorun olmayabilirdi. Ancak birden fazla olacağını biliyoruz çünkü onu web sayfamızda farklı tıbbi grupları oluşturmak için kullanıyoruz.

Böylece yeniden düzenleyebiliriz List liste öğeleri için daha dar sahne sağlamak için:

function List({ groupName, members = [] }) {
  return (
    <div>
      <h5>
        Group: <em>{groupName}</em>
      </h5>
      <ul>
        <p>Members</p>
        {members.map((member) => (
          <li key={member}>{member}</li>
        ))}
      </ul>
    </div>
  )
}

Bu biraz daha iyi görünüyor ve şimdi List şöyle:

import React from 'react'
import './styles.css'

function App() {
  const pediatricians = [
    'Michael Lopez',
    'Sally Tran',
    'Brian Lu',
    'Troy Sakulbulwanthana',
    'Lisa Wellington',
  ]

  const psychiatrists = [
    'Miguel Rodriduez',
    'Cassady Campbell',
    'Mike Torrence',
  ]

  return (
    <div className="root">
      <div className="listContainer">
        <List groupName="Pediatricians" members={pediatricians} />
      </div>
      <div className="listContainer">
        <List groupName="Psychiatrists" members={psychiatrists} />
      </div>
    </div>
  )
}

export default App

Burada stiller için fazla bir şey yok, ancak burada karışıklığı önlemek için:

.root {
  display: flex;
}

.listContainer {
  flex-grow: 1;
}

Sadece bu web sayfasıyla sınırlı küçük bir uygulama, muhtemelen bu basit bileşenle idare edebilir. Peki ya listenin yüzlerce satır oluşturması gereken potansiyel olarak büyük veri kümeleriyle uğraşıyorsak? Tümünü görüntülemeye çalışan bir sayfayla sonuçlanırdık, bu da kilitlenme, gecikme, öğelerin yerinde olmaması veya üst üste gelmesi vb. gibi sorunlara yol açabilir.

Bu harika bir kullanıcı deneyimi değil, bu nedenle üye sayısı belirli bir sayıya ulaştığında listeyi genişletmenin bir yolunu sağlayabiliriz:

function List({ groupName, members = [] }) {
  const [collapsed, setCollapsed] = React.useState(members.length > 3)

  const constrainedMembers = collapsed ? members.slice(0, 3) : members

  function toggle() {
    setCollapsed((prevValue) => !prevValue)
  }

  return (
    <div>
      <h5>
        Group: <em>{groupName}</em>
      </h5>
      <ul>
        <p>Members</p>
        {constrainedMembers.map((member) => (
          <li key={member}>{member}</li>
        ))}
        {members.length > 3 && (
          <li className="expand">
            <button type="button" onClick={toggle}>
              Expand
            </button>
          </li>
        )}
      </ul>
    </div>
  )
}

liste-genişletilebilir-tepki-bileşeni

.root {
  display: flex;
}

.listContainer {
  flex-grow: 1;
  box-sizing: border-box;
  width: 100%;
}

li.expand {
  list-style-type: none;
}

button {
  border: 0;
  border-radius: 4px;
  padding: 5px 10px;
  outline: none;
  cursor: pointer;
}

button:active {
  color: rgba(0, 0, 0, 0.75);
}

Görünüşe göre artık grup listelerini oluşturmak için oldukça iyi bir yeniden kullanılabilir bileşenimiz var.

Kesinlikle daha iyisini yapabiliriz. biz gerçekten Sahip olmak bu bileşeni özellikle bir kuruluşun grupları için kullanmak.

Ya başka amaçlar için kullanabilirsek? Etiket için bir destek sağlanması (bizim durumumuzda Group🙂 mantıksal olarak bunu gerçekleştirebilir:

function List({ label, groupName, members = [] }) {
  const [collapsed, setCollapsed] = React.useState(members.length > 3)

  const constrainedMembers = collapsed ? members.slice(0, 3) : members

  function toggle() {
    setCollapsed((prevValue) => !prevValue)
  }

  return (
    <div>
      <h5>
        {label}: <em>{groupName}</em>
      </h5>
      <ul>
        <p>Members</p>
        {constrainedMembers.map((member) => (
          <li key={member}>{member}</li>
        ))}
        {members.length > 3 && (
          <li className="expand">
            <button type="button" onClick={toggle}>
              Expand
            </button>
          </li>
        )}
      </ul>
    </div>
  )
}

Daha sonra başka amaçlar için kullanabilirsiniz:

function App() {
  return (
    <div className="root">
      <div className="listContainer">
        <List
          groupName="customerSupport"
          members={['Lousie Yu', 'Morgan Kelly']}
        />
      </div>
    </div>
  )
}

Ne zaman düşünmek Reaksiyon bileşenlerinin nasıl daha yeniden kullanılabilir hale getirileceği hakkında basit ama güçlü bir yaklaşım, prop değişkenlerinizin nasıl adlandırıldığını yeniden düşünün. Çoğu zaman basit bir yeniden adlandırma, Kocaman fark.

yani bizim içinde App bileşen için özel bir destek de sağlayabiliriz. Members Bölüm:

liste-üyeler-alt başlık

function List({ label, labelValue, sublabel, members = [] }) {
  const [collapsed, setCollapsed] = React.useState(members.length > 3)

  const constrainedMembers = collapsed ? members.slice(0, 3) : members

  function toggle() {
    setCollapsed((prevValue) => !prevValue)
  }

  return (
    <div>
      <h5>
        {label}: <em>{labelValue}</em>
      </h5>
      <ul>
        <p>{sublabel}</p>
        {constrainedMembers.map((member) => (
          <li key={member}>{member}</li>
        ))}
        {members.length > 3 && (
          <li className="expand">
            <button type="button" onClick={toggle}>
              Expand
            </button>
          </li>
        )}
      </ul>
    </div>
  )
}

Şimdi bileşenimize bakarsak ve sadece sağlamak members prop, ne elde ettiğimize bir bakalım:

liste-yeniden kullanılabilir-boş1

Sizi bilmem ama benim burada gördüğüm, listenin aslında herhangi bir şey!

Aynı bileşeni, bir sonraki randevuları için sırada bekleyen patentleri temsil etmek için yeniden kullanabiliriz:

doktor-randevu için-kuyrukta-doktor-hasta-listesi

Veya açık artırmalarda kullanabiliriz:

liste-teklifler-pug-tepki-yeniden kullanılabilir-bileşen

Yapmak olumsuzluk değişkenleri adlandırmanın gücünü hafife almak. Basit bir adlandırma düzeltmesi oyunun kurallarını değiştirebilir.

Hadi koda geri dönelim. Yeniden kullanılabilirliğini genişletme konusunda oldukça başarılıyız. Ama benim bakış açıma göre aslında bir çok daha fazla.

Yani şimdi bildiğimize göre List bileşen tamamen ilgisiz nedenlerle yeniden kullanılmak üzere uyumlu olabilir, artık aşağıdaki gibi farklı kullanım durumlarını desteklemek için bileşenin parçalarını alt bileşenlere ayırabileceğimize karar verebiliriz:

function ListRoot({ children, ...rest }) {
  return <div {...rest}>{children}</div>
}

function ListHeader({ children }) {
  return <h5>{children}</h5>
}

function ListComponent({ label, items = [], limit = 0 }) {
  const [collapsed, setCollapsed] = React.useState(items.length > 3)

  function toggle() {
    setCollapsed((prevValue) => !prevValue)
  }

  const constrainedItems = collapsed ? items.slice(0, limit) : items

  return (
    <ul>
      <p>{label}</p>
      {constrainedItems.map((member) => (
        <li key={member}>{member}</li>
      ))}
      {items.length > limit && (
        <li className="expand">
          <button type="button" onClick={toggle}>
            Expand
          </button>
        </li>
      )}
    </ul>
  )
}

function List({ header, label, members = [], limit }) {
  return (
    <ListRoot>
      <ListHeader>{header}</ListHeader>
      <ListComponent label={label} items={members} limit={limit} />
    </ListRoot>
  )
}

İşlevsel olarak aynı şekilde çalışır, ancak şimdi farklı öğeleri liste alt bileşenlerine ayırdık.

Bu, bazı düzgün faydalar sağladı:

  1. Artık her bileşeni ayrı ayrı test edebiliriz
  2. Daha ölçeklenebilir hale gelir (Bakım, kod boyutu)
  3. Kod büyüdüğünde bile daha okunabilir hale gelir
  4. gibi teknikleri kullanarak her bileşeni not alma ile optimize edin React.memo

Uygulama ayrıntılarının çoğunun aynı kaldı ama artık daha fazla yeniden kullanılabilir.

olduğunu fark etmiş olabilirsiniz collapsed devlet taşındı ListComponent. kolayca yapabiliriz ListComponent durum kontrolünü ebeveyne geri taşıyarak yeniden kullanılabilir sahne:

function ListComponent({ label, items = [], collapsed, toggle, limit, total }) {
  return (
    <ul>
      <p>{label}</p>
      {items.map((member) => (
        <li key={member}>{member}</li>
      ))}
      {total > limit && (
        <li className="expand">
          <button type="button" onClick={toggle}>
            {collapsed ? 'Expand' : 'Collapse'}
          </button>
        </li>
      )}
    </ul>
  )
}

function List({ header, label, items = [], limit = 3 }) {
  const [collapsed, setCollapsed] = React.useState(items.length > limit)

  function toggle() {
    setCollapsed((prevValue) => !prevValue)
  }

  return (
    <ListRoot>
      <ListHeader>{header}</ListHeader>
      <ListComponent
        label={label}
        items={
          collapsed && items.length > limit ? items.slice(0, limit) : items
        }
        collapsed={collapsed}
        toggle={toggle}
        limit={limit}
        total={items.length}
      />
    </ListRoot>
  )
}

Bilerek ListComponent sağlayarak daha yeniden kullanılabilir hale geldi. collapse sahne aracılığıyla devlet yönetimi, biz de aynısını yapabiliriz List böylece bileşenimizi kullanan geliştiriciler onu kontrol etme gücüne sahip olur:

function App() {
  const [collapsed, setCollapsed] = React.useState(true)

  function toggle() {
    setCollapsed((prevValue) => !prevValue)
  }

  const pediatricians = [
    'Michael Lopez',
    'Sally Tran',
    'Brian Lu',
    'Troy Sakulbulwanthana',
    'Lisa Wellington',
  ]

  const psychiatrists = [
    'Miguel Rodriduez',
    'Cassady Campbell',
    'Mike Torrence',
  ]

  const limit = 3

  return (
    <div className="root">
      <div className="listContainer">
        <List
          collapsed={collapsed}
          toggle={toggle}
          header="Bids on"
          label="Bidders"
          items={pediatricians}
          limit={limit}
        />
      </div>
      <div className="listContainer">
        <List header="Bids on" label="Bidders" items={psychiatrists} />
      </div>
    </div>
  )
}
function List({ collapsed, toggle, header, label, items = [], limit = 3 }) {
  return (
    <ListRoot>
      <ListHeader>{header}</ListHeader>
      <ListComponent
        label={label}
        items={
          collapsed && items.length > limit ? items.slice(0, limit) : items
        }
        collapsed={collapsed}
        toggle={toggle}
        limit={limit}
        total={items.length}
      />
    </ListRoot>
  )
}

list-expandable-delegated-collapse-state-react-component.gif

Burada bir modelin ortaya çıktığını görmeye başlıyoruz. Görünüşe göre props yeniden kullanılabilirlikle çok ilgisi var – ve bu kesinlikle doğru!

Uygulamada, geliştiricilerin kendi bileşenlerini sağlamak için bir alt bileşenin bir uygulamasını geçersiz kılmak istemeleri nadir değildir. bizim yapabiliriz List Bileşenlerden de bir geçersiz kılıcı sağlayarak buna izin vermek için bileşen:

function List({
  collapsed,
  toggle,
  header,
  label,
  items = [],
  limit = 3,
  renderHeader,
  renderList,
}) {
  return (
    <ListRoot>
      {renderHeader ? renderHeader() : <ListHeader>{header}</ListHeader>}
      {renderList ? (
        renderList()
      ) : (
        <ListComponent
          label={label}
          items={
            collapsed && items.length > limit ? items.slice(0, limit) : items
          }
          collapsed={collapsed}
          toggle={toggle}
          limit={limit}
          total={items.length}
        />
      )}
    </ListRoot>
  )
}

Bu, birçok tepki kitaplığında kullanılan çok yaygın ancak güçlü bir kalıptır. Yeniden kullanılabilirliğin ortasında, her zaman varsayılan uygulamaların yerinde olması çok önemlidir. Örneğin, bir geliştirici geçersiz kılmak isterse ListHeader geçerek kendi uygulamasını sağlayabilir. renderHeaderaksi takdirde orijinali oluşturmak için varsayılan olacaktır ListHeader. Bu, liste bileşeninin işlevsel olarak aynı ve kırılmaz kalmasını sağlamak içindir.

Ancak, bir geçersiz kılıcı kullanılmıyorsa varsayılan uygulamalar sağlasanız bile, bir yol sağlamak da iyidir. kaldırmak veya saklamak bileşende de bir şey.

Örneğin, bir geliştirici için bir yol sağlamak istiyorsak olumsuzluk herhangi bir başlık öğesini oluştur hiçsağlamak için yararlı bir taktiktir. “değiştirmek” bunun için sahne aracılığıyla. Ad alanını kirletmek istemiyoruz sahnede yeniden kullanabilmemiz için header prop, böylece içeri girerlerse null liste başlığını hiç oluşturamaz:

function List({
  collapsed,
  toggle,
  header,
  label,
  items = [],
  limit = 3,
  renderHeader,
  renderList,
}) {
  return (
    <ListRoot>
      {renderHeader ? (
        renderHeader()
      ) : 
      header !== null ? (
        <ListHeader>{header}</ListHeader>
      ) : null}

      {renderList ? (
        renderList()
      ) : (
        <ListComponent
          label={label}
          items={
            collapsed && items.length > limit ? items.slice(0, limit) : items
          }
          collapsed={collapsed}
          toggle={toggle}
          limit={limit}
          total={items.length}
        />
      )}
    </ListRoot>
  )
}
<List
  collapsed={collapsed}
  toggle={toggle}
  header={null} 
  label="Bidders"
  items={pediatricians}
  limit={limit}
/>

liste-başlık-gizle

Yeniden kullanılabilirliğimizle hala daha ileri gidebiliriz List bileşen. için geçersiz kılıcılar sağlamakla sınırlı değiliz. ListHeader ve ListComponent. Ayrıca, bunları geçersiz kılmaları için bir yol sağlayabiliriz. kök bileşen şöyle:

function List({
  component: RootComponent = ListRoot,
  collapsed,
  toggle,
  header,
  label,
  items = [],
  limit = 3,
  renderHeader,
  renderList,
}) {
  return (
    <RootComponent>
      {renderHeader ? (
        renderHeader()
      ) : header !== null ? (
        <ListHeader>{header}</ListHeader>
      ) : null}
      {renderList ? (
        renderList()
      ) : (
        <ListComponent
          label={label}
          items={
            collapsed && items.length > limit ? items.slice(0, limit) : items
          }
          collapsed={collapsed}
          toggle={toggle}
          limit={limit}
          total={items.length}
        />
      )}
    </RootComponent>
  )
}

Bunun gibi özelleştirilebilir seçenekler sağladığımızda, her zaman varsayılan bir uygulamayı varsayılan olarak kullandığımızı, tıpkı orijinali kullanmak üzere varsayılan olarak ayarladığımızı unutmayın. ListRoot bileşen.

Artık ebeveyn, kendi modaya uygun konteyner bileşenlerini kolayca sağlayabilir. List çocukları olarak:

function App() {
  const [collapsed, setCollapsed] = React.useState(true)

  function toggle() {
    setCollapsed((prevValue) => !prevValue)
  }

  const pediatricians = [
    'Michael Lopez',
    'Sally Tran',
    'Brian Lu',
    'Troy Sakulbulwanthana',
    'Lisa Wellington',
  ]

  const psychiatrists = [
    'Miguel Rodriduez',
    'Cassady Campbell',
    'Mike Torrence',
  ]

  const limit = 3

  function BeautifulListContainer({ children }) {
    return (
      <div
        style={{
          background: 'teal',
          padding: 12,
          borderRadius: 4,
          color: '#fff',
        }}
      >
        {children}
        Today is: {new Date().toDateString()}
      </div>
    )
  }

  return (
    <div className="root">
      <div className="listContainer">
        <List
          component={BeautifulListContainer}
          collapsed={collapsed}
          toggle={toggle}
          header={null}
          label="Bidders"
          items={pediatricians}
          limit={limit}
        />
      </div>
      <div className="listContainer">
        <List header="Bids on" label="Bidders" items={psychiatrists} />
      </div>
    </div>
  )
}

liste-genişletilebilir-temsilci-collapse-durum-tepki-bileşen-özel-kök-bileşen

Bazen geliştiriciler de kendi listelerini sağlamak isterler. sıras, yani bu gönderi boyunca bahsettiğimiz kavramları kullanarak bunu gerçekleştirebiliriz. Önce şunu soyutlayalım li elementler kendi içlerinde ListItem bileşen:

function ListComponent({ label, items = [], collapsed, toggle, limit, total }) {
  return (
    <ul>
      <p>{label}</p>
      {items.map((member) => (
        <ListItem key={member}>{member}</ListItem>
      ))}
      {total > limit && (
        <ListItem className="expand">
          <button type="button" onClick={toggle}>
            {collapsed ? 'Expand' : 'Collapse'}
          </button>
        </ListItem>
      )}
    </ul>
  )
}

function ListItem({ children, ...rest }) {
  return <li {...rest}>{children}</li>
}

Sonra değiştir List varsayılanı geçersiz kılmak için özelleştirilebilir bir oluşturucu sağlamak için ListItem:

function List({
  component: RootComponent = ListRoot,
  collapsed,
  toggle,
  header,
  label,
  items = [],
  limit = 3,
  renderHeader,
  renderList,
  renderListItem,
}) {
  return (
    <RootComponent>
      {renderHeader ? (
        renderHeader()
      ) : header !== null ? (
        <ListHeader>{header}</ListHeader>
      ) : null}
      {renderList ? (
        renderList()
      ) : (
        <ListComponent
          label={label}
          items={
            collapsed && items.length > limit ? items.slice(0, limit) : items
          }
          collapsed={collapsed}
          toggle={toggle}
          limit={limit}
          total={items.length}
          renderListItem={renderListItem}
        />
      )}
    </RootComponent>
  )
}

Ve biraz değiştirin ListComponent bu özelleştirmeyi desteklemek için:

function ListComponent({
  label,
  items = [],
  collapsed,
  toggle,
  limit,
  total,
  renderListItem,
}) {
  return (
    <ul>
      <p>{label}</p>
      {items.map((member) =>
        renderListItem ? (
          <React.Fragment key={member}>{renderListItem({ collapsed, toggle, member )}</React.Fragment>
        ) : (
          <ListItem key={member}>{member}</ListItem>
        ),
      )}
      {total > limit && (
        <ListItem className='expand'>
          <button type='button' onClick={toggle}>
            {collapsed ? 'Expand' : 'Collapse'}
          </button>
        </ListItem>
      )}
    </ul>
  )
}

Not: Çağrıyı tamamladık. renderListItem(member) içinde React.Fragment atamayı halledebilmemiz için key zorunda kalmasınlar diye onlar için. Bu basit değişiklik, bileşenimizi deneyen kullanıcılardan olumlu yorumlar alma konusunda fark yaratabilir, çünkü bu, onları kendi başlarına halletme zahmetinden kurtaracaktır.

Bir tepki geliştiricisi olarak, hedeflerimizi en üst düzeye çıkarmak için hala çok daha fazla açık fırsat görüyorum. List bileşenin tam potansiyeline kadar yeniden kullanılabilirliği. Ancak bu noktada yazı çok uzun olduğu için, yolculuğunuza başlamak için birkaç tane daha ile bitireceğim 🙂

Şunu vurgulamak isterim ki, aşağıdaki gibi oluşturucu donanımlarından yararlanmamızın önemli olduğunu renderListItem veya renderHeader argümanları arayana geri iletmek için. Bu güçlü bir kalıptır ve render destek kalıbının tepki kancaları serbest bırakılmadan önce yaygın olarak benimsenmesinin nedeni budur.

Prop değişkenlerimizi adlandırmaya geri dönersek, bu bileşenin aslında ihtiyaç her seferinde bir listeyi temsil etmek için. Bunu aslında sadece listeleri oluşturmak için değil, birçok farklı durum için uyumlu hale getirebiliriz! asıl dikkat etmemiz gereken bileşenin nasıl uygulandığı kodda.

Esasen yaptığı tek şey, öğelerin bir listesini almak ve bunları işlemek., çökme gibi süslü özellikleri desteklerken. Daralan kısım sadece açılır menülere, listelere, menülere vb. özelmiş gibi gelebilir. Ancak her şey daraltılabilir! Bileşenimizdeki herhangi bir şey yalnızca bu bileşenlere özgü değildir.

Örneğin, bileşeni bir gezinme çubuğu için kolayca yeniden kullanabiliriz:

liste-genişletilebilir-yeniden kullanılabilir-navbar-tepki-bileşeni

Bileşenimiz, aşağıdaki gibi birkaç sahne daha sağlamamız dışında, temelde öncekiyle aynıdır. renderCollapser ve renderExpander:

function ListComponent({
  label,
  items = [],
  collapsed,
  toggle,
  limit,
  total,
  renderListItem,
  renderCollapser,
  renderExpander,
}) {
  let expandCollapse

  if (total > limit) {
    if (collapsed) {
      expandCollapse = renderExpander ? (
        renderExpander({ collapsed, toggle })
      ) : (
        <button type="button" onClick={toggle}>
          Expand
        </button>
      )
    } else {
      expandCollapse = renderCollapser ? (
        renderCollapser({ collapsed, toggle })
      ) : (
        <button type="button" onClick={toggle}>
          Collapse
        </button>
      )
    }
  }

  return (
    <ul>
      <p>{label}</p>
      {items.map((member) =>
        renderListItem ? (
          <React.Fragment key={member}>
            {renderListItem({ collapsed, toggle, member })}
          </React.Fragment>
        ) : (
          <ListItem key={member}>{member}</ListItem>
        ),
      )}
      {total > limit && (
        <ListItem className="expand">{expandCollapse}</ListItem>
      )}
    </ul>
  )
}

function ListItem({ children, ...rest }) {
  return <li {...rest}>{children}</li>
}

function List({
  component: RootComponent = ListRoot,
  collapsed,
  toggle,
  header,
  label,
  items = [],
  limit = 3,
  renderHeader,
  renderList,
  renderListItem,
  renderCollapser,
  renderExpander,
}) {
  return (
    <RootComponent>
      {renderHeader ? (
        renderHeader()
      ) : header !== null ? (
        <ListHeader>{header}</ListHeader>
      ) : null}
      {renderList ? (
        renderList()
      ) : (
        <ListComponent
          label={label}
          items={
            collapsed && items.length > limit ? items.slice(0, limit) : items
          }
          collapsed={collapsed}
          toggle={toggle}
          limit={limit}
          total={items.length}
          renderListItem={renderListItem}
          renderCollapser={renderCollapser}
          renderExpander={renderExpander}
        />
      )}
    </RootComponent>
  )
}
function App() {
  const [collapsed, setCollapsed] = React.useState(true)

  function toggle() {
    setCollapsed((prevValue) => !prevValue)
  }

  const pediatricians = ['Home', 'Posts', 'About', 'More', 'Contact', 'FAQ']
  const limit = 3

  function renderCollapser({ collapsed, toggle }) {
    return <ChevronLeftIcon onClick={toggle} />
  }

  function renderExpander({ collapsed, toggle }) {
    return <ChevronRightIcon onClick={toggle} />
  }

  function renderListItem({ collapsed, toggle, member }) {
    function onClick() {
      window.alert(`Clicked ${member}`)
    }
    return (
      <li className="custom-li" onClick={onClick}>
        {member}
      </li>
    )
  }

  return (
    <div className="navbar">
      <div className="listContainer">
        <List
          collapsed={collapsed}
          toggle={toggle}
          header={null}
          items={pediatricians}
          limit={limit}
          renderCollapser={renderCollapser}
          renderExpander={renderExpander}
          renderListItem={renderListItem}
        />
      </div>
    </div>
  )
}

Ve bu, yeniden kullanılabilirliği en üst düzeye çıkarmanın gücüdür!

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.