
Kutu bileşenleri en temel ancak güçlü Reaksiyon uygulamalarında kullanılacak bileşenler. Davranışları basittir, ancak bu basitlik, daha karmaşık bileşenleri bir araya getirmenin temel temelidir ve modern kullanıcı arayüzleri oluşturmak için sonsuz olasılıklara izin verir.
Bu yazıda, fonksiyon içinde sadece birkaç basit uygulama ile tepki veren güçlü bir yeniden kullanılabilir kutu bileşeni oluşturacağız.
Vakfı yaz
Yapacağımız ilk şey kendimizi tanımlamaktır. Box
ile bileşen çıplak minimum şöyle:
function Box({ children, ...props }) {
return <div {...props}>{children}</div>
}
Burada zaten görülecek iki önemli şey var:
- Seçtiğimiz eleman
div
. Bu, her yeniden kullanılabilir bileşenin başlaması gereken DOM’daki en temel öğedir. Varsayılan olarak bir tüm blok. Öğe, tam tersi olmak yerine, gerekirse yapılandırmamız gereken tüm genişliği kaplıyorsa daha sezgiseldir. - Biz yıkmak
children
ve manuel olarak bizim için uygulaBox
bileşen. Bunu her zaman, her bileşenle yapmayı seviyorum. çocukları bekliyor Çünkü o bir net gösterge ebeveynin bazı tepki düğümlerinden geçmeyi bekleyeceği. Aynı zamanda en iyi uygulamadır ve bu şekilde yapmak, içeri aktarmak yerine daha fazla fayda sağlar.props
gizemli bir şekilde uygulandığı yer. Gizem, React’in bildirimsel doğasına aykırıdır.
Artık onu işimizde kullanabiliriz. App
bileşen:
import React from 'react'
function Box({ children, ...props }) {
return <div {...props}>{children}</div>
}
export default function App() {
return <Box>Sally Montgomery</Box>
}
Bu öğretici uğruna, devam ederken neyin uygulandığını açıkça görebilmemiz için ana bileşende önceden bazı stillerden geçeceğiz:
import React from 'react'
function Box({ children, ...props }) {
return <div {...props}>{children}</div>
}
export default function App() {
return (
<Box
style={{
backgroundColor: '#333',
borderRadius: 4,
color: '#eee',
minHeight: 200,
padding: 12,
width: 300,
}}
>
Sally Montgomery
</Box>
)
}
Ebeveyn Olmak için ebeveyn
bizim yeniden kullanılabilir Box
bileşen abilir burada bitecek, ancak içine daha fazla yetenek sıkıştırmak istiyorsak yeniden kullanılabilirlikteki mevcut yeteneğini azaltmadan bizim özelleştirebiliriz Box
daha fazla sahne kabul etmek ve bunları işlemek için uygulama ebeveynin onları yönetmesine izin vermeden.
Ebeveynin olduğu durumlar vardır. meli bazı sahne malzemelerini ele al, ama olmalılar isteyen yapılandırabilmek gibi bunları işlemek için style
zaten yukarıda sahip olduğumuz nesne.
bizim içinde App
bileşen bazı stil aksesuarları uyguladık:
export default function App() {
return (
<Box
style={{
backgroundColor: '#333',
borderRadius: 4,
color: '#eee',
minHeight: 200,
padding: 12,
width: 300,
}}
>
Sally Montgomery
</Box>
)
}
Bunu neden yaptık? Çünkü biz olmasaydık Box
şöyle görünecek:
Bunu düşün. Box bileşenimizi içe aktaran her bileşen içeri aktarılacak mı? style
her zaman? Büyük olasılıkla, aksi takdirde sadece bir div
öğe.
Ebeveynin bir açıklama yapmasına gerek kalmadan bazı stil aksesuarlarının geçmesine izin verebiliriz. style
her zaman nesne:
(not: Bu yazının ilerleyen kısımlarında kullanacağım ekstra aksesuarlar ekledim)
function Box({
children,
backgroundColor,
border,
borderRadius,
color,
overflow,
fontFamily,
fontSize,
fontWeight,
minHeight,
margin,
padding,
width,
textAlign,
style,
...props
}) {
return (
<div
{...props}
style={{
border,
backgroundColor,
borderRadius,
color,
fontFamily,
fontSize,
fontWeight,
overflow,
minHeight,
margin,
padding,
width,
textAlign,
...style,
}}
>
{children}
</div>
)
}
Bu şekilde bileşenlerimiz bir bütün olarak manuel olarak geçmek zorunda kalmayacak style
birkaç stili değiştirmek için nesne:
export default function App() {
return (
<Box
backgroundColor="#333"
borderRadius={4}
color="#eee"
minHeight={200}
padding={12}
width={300}
>
Sally Montgomery
</Box>
)
}
Ayrıca içimizde olduğundan emin olduk. Box
bileşeni yerleştirdiğimiz style
diğerlerini geçersiz kılabilmesi için en son destek ebeveyn ne zaman isterse:
Bu, popüler kütüphanelerin sevdiği çok uygun bir stratejidir. @çakra-ui/tepki geliştirme deneyimini iyileştiren şeyi yapın (buradaki amaç kullanıcıları bu yola yönlendirmek olduğu için bu gönderinin yapmayacağı şeyi tamamen özelleştirdiler).
Daha hızlı, daha kolay, kodu ve ortak plakayı azaltır.
hadi kullanalım Box
oluşturmak için bileşen kart:
export default function App() {
return (
<Box
backgroundColor="#333"
borderRadius={4}
color="#eee"
minHeight={200}
padding={12}
width={300}
>
<Box>
<img alt="Profile" src="./images/woman.png" style={{ width: 70 }} />
</Box>
<Box>Sally Montgomery</Box>
<Box>
About me: I am a hard working individual who strives for success. I have
a puppy named Cookie that I love very much because she always prevents
me from falling into emotional thoughts and keeps me going.
</Box>
<Box></Box>
</Box>
)
}
(Kadın avatarı şuradan alınmıştır: ücretsiz)
Şimdiden iyi görünüyorsun! Ancak kadın imajımıza biraz boşluk, yazı tipi stili ve kenarlık uygulamamız gerekiyor, bu bizim için kolaylaştırdığımız için kolayca yapılabilir. Box
.
Daha Fazlasını Yapın, Daha Az Çalışın
export default function App() {
return (
<Box
backgroundColor="#333"
borderRadius={4}
color="#eee"
minHeight={200}
padding={20}
width={300}
>
<Box
width={80}
border="4px solid cyan"
backgroundColor="#fff"
borderRadius="50%"
overflow="hidden"
>
<img alt="Profile" src={woman} style={{ width: '100%' }} />
</Box>
<Box fontFamily="Helvetica" fontSize="1.3rem" padding="10px 0">
Sally Montgomery
</Box>
<Box fontFamily="Helvetica" fontWeight={300}>
About me: I am a hard working individual who strives for success. I have
a puppy named Cookie that I love very much because she always prevents
me from falling into emotional thoughts and keeps me going.
</Box>
<Box></Box>
</Box>
)
}
daha da optimize edebiliriz Box
Bileşenlerini varsayılan olarak ayarlayarak ana bileşenlerin birlikte çalışmasını daha da kolaylaştırmak için bileşen. Her uygulamanın bir dizi varsayılanı vardır yazı tipi uygulama boyunca kullanılacak stiller, bu yüzden Box
yazı tipinde bu aksesuarlar için varsayılan:
function Box({
children,
backgroundColor,
border,
borderRadius,
color,
overflow,
fontFamily = 'Helvetica',
fontSize = '1rem',
fontWeight = 300,
minHeight,
margin,
padding,
width,
textAlign,
style,
...props
}) {
return (
<div
{...props}
style={{
border,
backgroundColor,
borderRadius,
color,
fontFamily,
fontSize,
fontWeight,
overflow,
minHeight,
margin,
padding,
width,
textAlign,
...style,
}}
>
{children}
</div>
)
}
Artık kodlarımızdaki bazı kodları kaldırabiliriz. App
bizim beri Box
bunları varsayılan olarak işler:
export default function App() {
return (
<Box
backgroundColor="#333"
borderRadius={4}
color="#eee"
minHeight={200}
padding={20}
width={300}
>
<Box
width={80}
border="4px solid cyan"
backgroundColor="#fff"
borderRadius="50%"
overflow="hidden"
>
<img alt="Profile" src={woman} style={{ width: '100%' }} />
</Box>
<Box fontSize="1.3rem" padding="10px 0">
Sally Montgomery
</Box>
<Box>
About me: I am a hard working individual who strives for success. I have
a puppy named Cookie that I love very much because she always prevents
me from falling into emotional thoughts and keeps me going.
</Box>
<Box></Box>
</Box>
)
}
Bizimle ilgili harika bir şey Box
bileşen, olabileceği oluşan yaratmak daha karmaşık yeniden kullanılabilir bileşenler. Burası bizim yeniden kullanılabilirliğimizin olduğu yer Box
bileşen Gerçekten parlıyor çünkü zaten temel kalıpları soyutluyor, böylece temel ihtiyaçlar hakkında endişelenmeden her yerde kullanılabilecekler:
function Card({ avatar, title, children, ...rootProps }) {
return (
<Box
backgroundColor="#333"
borderRadius={4}
color="#eee"
minHeight={200}
padding={20}
width={300}
{...rootProps}
>
{avatar ? (
<Box
width={80}
border="4px solid cyan"
backgroundColor="#fff"
borderRadius="50%"
overflow="hidden"
>
{avatar}
</Box>
) : null}
{title ? (
<Box fontSize="1.3rem" padding="10px 0">
{title}
</Box>
) : null}
{children ? <Box>{children}</Box> : null}
</Box>
)
}
export default function App() {
return (
<Card
avatar={<img alt="Profile" src={woman} style={{ width: '100%' }} />}
title="Sally Montgomery"
>
About me: I am a hard working individual who strives for success. I have a
puppy named Cookie that I love very much because she always prevents me
from falling into emotional thoughts and keeps me going.
</Card>
)
}
Kazan Plakası Geri Döndüğünde. Daha Sert Geri Vurursun
Burada bir gün diyebiliriz. Ama yakından bakarsan, görmeye başlıyoruz Box
her yerde, bu yüzden sonunda tekrar ortak kod yazma sorununu ortaya çıkarır.
Bazı tepki kitaplıklarının yararlandığı ve bizim için kullanabileceğimiz güçlü bir strateji var. Box
bileşen. Ebeveynin özel bir tepki öğesi, öğe etiketi veya bileşen olarak prop olarak geçmesine izin veren bir parametre bildirebiliriz:
function Box({
as: asProp = 'div',
children,
backgroundColor,
border,
borderRadius,
color,
overflow,
fontFamily = 'Helvetica',
fontSize = '1rem',
fontWeight = 300,
minHeight,
margin,
padding,
width,
textAlign,
style,
...props
}) {
const Component = asProp
return (
<Component
{...props}
style={{
border,
backgroundColor,
borderRadius,
color,
fontFamily,
fontSize,
fontWeight,
overflow,
minHeight,
margin,
padding,
width,
textAlign,
...style,
}}
>
{children}
</Component>
)
}
Daha Az Kaynak
Bununla birlikte, bizim gibi yerlerde kullanıldığında kullanışlı olabilir. Card
:
Bunu yapmak güzel bir fayda sağlar: Kaldırırız bir bileşen eksik sanal dom içinde oluşturuluyor. Daha fazla bileşende yoğun olarak kullanıldığında GPU’nuz size teşekkür edecektir.
Tembelliği Teşvik Etmek
Bir başka şey. Ayrıca, sahne malzemelerinin tembel yollarla uygulanmasına da olanak tanır. Örneğin, aşağıdan beri avatar sahnelerimizi oluşturduğumuzda Box
doğrudan bundan faydalanabileceğimiz bir bileşen olabilir ve bunun gibi süper tembel olabiliriz:
const getCardAvatarProps = (avatar) => {
return {
as: 'img',
width: 80,
border: '4px solid cyan',
backgroundColor: '#fff',
borderRadius: '50%',
overflow: 'hidden',
...(typeof avatar === 'string'
? { src: avatar }
: React.isValidElement(avatar)
? { children: avatar }
: avatar),
}
}
function Card({ avatar, title, children, ...rootProps }) {
return (
<Box
backgroundColor="#333"
borderRadius={4}
color="#eee"
minHeight={200}
padding={20}
width={300}
{...rootProps}
>
<Box {...getCardAvatarProps(avatar)} />>
{title ? (
<Box fontSize="1.3rem" padding="10px 0">
{title}
</Box>
) : null}
{children ? <Box>{children}</Box> : null}
</Box>
)
}
ön ayarlar
Ve listemize ekleyebileceğimiz bir başka yararlı şey Box
belirli aksesuarlar için bir dizi “ön ayar”a izin vermektir.
Örneğin, izin verebiliriz fontSize
olarak geçirilecek 'xl'
, 'lg'
, 'md'
, 'sm'
veya 'xs'
. Bunlardan hiçbiri sağlanmazsa, yalnızca sağlanan değeri uygular. Bu iter Box
ile çalışmak daha kolay olma yeteneklerinde daha da ileri:
function Box({
as: asProp = 'div',
children,
backgroundColor,
border,
borderRadius,
color,
mode = 'default',
overflow,
fontFamily = 'Helvetica',
fontSize = '1rem',
fontWeight = 300,
minHeight,
margin,
padding,
width,
textAlign,
style,
...props
}) {
const Component = asProp
let modeStyles
if (mode === 'modal') {
modeStyles = {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
border: '12px solid #19A8F7',
flexDirection: 'column',
backgroundColor: '#1F3F50',
color: '#eee',
}
} else if (mode === 'card') {
modeStyles = {
backgroundColor: '#fff',
color: 'rgba(0, 0, 0, 0.75)',
paddingBottom: 30,
}
}
const otherStyles = {
border,
backgroundColor,
borderRadius,
color,
fontFamily,
fontSize,
fontWeight,
overflow,
minHeight,
margin,
padding,
width,
textAlign,
}
if (fontSize) {
if (fontSize === 'xl') otherStyles.fontSize = '2rem'
else if (fontSize === 'lg') otherStyles.fontSize = '1.5rem'
else if (fontSize === 'md') otherStyles.fontSize = '1.2rem'
else if (fontSize === 'sm') otherStyles.fontSize = '1rem'
else if (fontSize === 'xs') otherStyles.fontSize = '0.8rem'
}
return (
<Component
{...props}
style={{
...otherStyles,
...style,
...modeStyles,
}}
>
{children}
</Component>
)
}
bu Card
bileşenin bunu bilmesine bile gerek yoktur ve sağladığı faydaları elde etmek için sahne öğelerini iletebilir. Örneğin, işlenirken title
prop sadece bir nesneyi alabilir ve onu bir gün olarak adlandırabilir:
const getCardTitleProps = (title) => {
return typeof title === 'string' ? { children: title } : title
}
function Card({ avatar, title, children, mode, ...rootProps }) {
return (
<Box
backgroundColor="#333"
borderRadius={4}
color="#eee"
minHeight={200}
padding={20}
width={300}
mode={mode}
{...rootProps}
>
{avatar ? (
<Box
as={typeof avatar === 'string' ? 'img' : undefined}
width={80}
border="4px solid cyan"
backgroundColor="#fff"
borderRadius="50%"
overflow="hidden"
src={typeof avatar === 'string' ? avatar : undefined}
>
{typeof avatar === 'string' ? null : avatar}
</Box>
) : null}
<Box fontSize="1.3rem" padding="10px 0" {...getCardTitleProps(title)} />
{children ? <Box>{children}</Box> : null}
</Box>
)
}
Uygulamanızda uzmanlaşmak için bir araya getirme
Burada bahsetmek istediğim son bir şey, benim için yapmayı sevdiğim şey. Box
uygulamam için özelleşmiş bileşenler. oluşturmak için yararlıdır mode
duruma göre stilleri değiştirecek olan ve farklı bir “hissetmek” ona:
function Box({
as: asProp = 'div',
children,
backgroundColor,
border,
borderRadius,
color,
mode = 'default',
overflow,
fontFamily = 'Helvetica',
fontSize = '1rem',
fontWeight = 300,
minHeight,
margin,
padding,
width,
textAlign,
style,
...props
}) {
const Component = asProp
let modeStyles
if (mode === 'modal') {
modeStyles = {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
border: '12px solid #19A8F7',
flexDirection: 'column',
backgroundColor: '#1F3F50',
color: '#eee',
}
} else if (mode === 'card') {
modeStyles = {
backgroundColor: '#fff',
color: 'rgba(0, 0, 0, 0.75)',
paddingBottom: 30,
}
}
return (
<Component
{...props}
style={{
border,
backgroundColor,
borderRadius,
color,
fontFamily,
fontSize,
fontWeight,
overflow,
minHeight,
margin,
padding,
width,
textAlign,
...style,
...modeStyles,
}}
>
{children}
</Component>
)
}
export default function App() {
return (
<Card avatar={woman} title="Sally Montgomery" mode="modal">
About me: I am a hard working individual who strives for success. I have a
puppy named Cookie that I love very much because she always prevents me
from falling into emotional thoughts and keeps me going.
</Card>
)
}
Sonuç:
export default function App() {
return (
<Card avatar={woman} title="Sally Montgomery" mode="card">
About me: I am a hard working individual who strives for success. I have a
puppy named Cookie that I love very much because she always prevents me
from falling into emotional thoughts and keeps me going.
</Card>
)
}
Sonuç:
Özelleştirilmiş stiller uygularken, herhangi bir genişlik/yükseklik veya herhangi bir konumlandırma ayarlamamak, bunun yerine ebeveynin bunları özelleştirmesine izin vermek en iyisidir. Aksi takdirde, örtüşen öğeler gibi bir sorunla karşılaştıklarında, Box
kendi bileşenleriyle kombinasyon halinde satır içi.
Çözüm
Ve bu yazının sonu burada bitiyor! Bunu değerli bulduğunuzu ve gelecekte daha fazlasını aradığınızı fark ettim!