Tarz bileşenleri kullanarak React Uygulamalarında Karanlık Modu Uygulama
Yayınlanan: 2022-03-10En sık istenen yazılım özelliklerinden biri karanlık moddur (veya diğerlerinin dediği gibi gece modu). Her gün kullandığımız uygulamalarda karanlık mod görüyoruz. Mobil uygulamalardan web uygulamalarına kadar, karanlık mod, kullanıcılarının gözleriyle ilgilenmek isteyen şirketler için hayati hale geldi.
Karanlık mod, kullanıcı arayüzünde çoğunlukla karanlık yüzeyleri görüntüleyen ek bir özelliktir. Çoğu büyük şirket (YouTube, Twitter ve Netflix gibi) mobil ve web uygulamalarında karanlık modu benimsemiştir.
React ve stil bileşenlerine derinlemesine girmeyecek olsak da, temel bir React, CSS ve stilli bileşenler bilgisi kullanışlı olacaktır. Bu eğitim, karanlık modu sevenlere hitap ederek web uygulamalarını geliştirmek isteyenlere fayda sağlayacaktır.
Bu makalenin yazılmasından birkaç gün önce StackOverflow, kullanıcılara iki mod arasında geçiş yapma şansı vererek karanlık modu yayınladığını duyurdu.
Karanlık mod, göz yorgunluğunu azaltır ve bir bilgisayarda veya cep telefonunda uzun süre çalıştığınızda yardımcı olur.
Karanlık Mod Nedir?
Koyu mod, ekranın cep telefonlarına, tabletlere ve bilgisayarlara bakılmasını biraz daha kolaylaştıran, koyu renkli bir arka plan üzerinde açık metin ve arabirim öğeleri görüntüleyen herhangi bir arabirimin renk şemasıdır. Karanlık mod, okunabilirlik için gereken minimum renk kontrast oranlarını korurken ekranın yaydığı ışığı azaltır.
Neden Karanlık Modu Önemsemelisiniz?
Karanlık mod, göz yorgunluğunu azaltarak, ekranı mevcut ışık koşullarına göre ayarlayarak ve gece veya karanlık ortamlarda kullanım kolaylığı sağlayarak görsel ergonomiyi geliştirir.
Uygulamamızda karanlık modu uygulamadan önce faydalarına bir göz atalım.
Pil Tasarrufu
Web ve mobil uygulamalardaki karanlık mod, bir cihazın pil ömrünü uzatabilir. Google, OLED ekranlardaki karanlık modun pil ömrüne çok yardımcı olduğunu onayladı.
Örneğin, %50 parlaklıkta YouTube uygulamasındaki karanlık mod, düz beyaz bir arka plana göre yaklaşık %15 daha fazla ekran enerjisi tasarrufu sağlar. %100 ekran parlaklığında, karanlık arayüz ekran enerjisinden %60 gibi büyük bir tasarruf sağlar.
Karanlık Mod Güzeldir
Karanlık mod güzeldir ve ekranın çekiciliğini önemli ölçüde artırabilir.
Çoğu ürün bu benzer beyaz görünüm için giderken, karanlık mod gizemli ve yeni hissettiren farklı bir şey sunar.
Ayrıca panolar, resimler ve fotoğraflar gibi grafik içeriği yeni bir şekilde sunmak için harika fırsatlar sunar.
Artık bir sonraki web uygulamanızda neden karanlık modu uygulamanız gerektiğini bildiğinize göre, bu öğreticinin tanımlayıcı kaynağı olan stil bileşenlerinin derinliklerine inelim.
Koyu mod, açık renkli metin ve arabirim öğelerini koyu bir arka plan üzerinde görüntüleyen herhangi bir arabirimin renk şemasıdır; bu, cep telefonlarında, tabletlerde ve bilgisayarlarda bakmayı biraz daha kolaylaştırır.
“
Tarz bileşenleri nelerdir?
Bu makale boyunca, stil bileşenleri kitaplığını çok sık kullanacağız. Modern bir web uygulamasına stil vermenin her zaman birçok yolu olmuştur. Bir index.css
dosyası oluşturmayı ve onu HTML'ye bağlamayı veya HTML dosyası içinde stil oluşturmayı içeren, belge düzeyinde geleneksel stil oluşturma yöntemi vardır.
CSS-in-JS'nin tanıtılmasından bu yana, web uygulamalarının biçimlendirilme şekillerinde çok şey değişti.
CSS-in-JS, CSS'nin JavaScript kullanılarak oluşturulduğu bir kalıbı ifade eder. Bir JavaScript dosyasındaki bileşenleri biçimlendirmek için etiketli şablon değişmezlerini kullanır.
CSS-in-JS hakkında daha fazla bilgi edinmek için Anna Monus'un konuyla ilgili makalesine göz atın.
styled-components bir CSS-in-JS kitaplığıdır; ortam sorguları, sözde seçiciler ve iç içe yerleştirme dahil olmak üzere CSS'nin sevdiğiniz tüm özelliklerini kullanmanıza olanak tanır.
Neden stil bileşenleri?
styled-components aşağıdaki nedenlerle oluşturulmuştur:
- Sınıf adı cehennem yok
Bir öğe için bir sınıf adı bulmak için kafanızı karıştırmak yerine, stilli bileşenler, stilleriniz için benzersiz sınıf adları oluşturur. Yazım hataları veya anlamı olmayan sınıf adları kullanma konusunda asla endişelenmenize gerek kalmayacak. - sahne kullanma
styled-components, React'te yaygın olarak kullanılanprops
parametresini kullanarak stil özelliklerini genişletmemize olanak tanır - böylece, uygulamanın durumu aracılığıyla bir bileşenin hissini dinamik olarak etkiler. - Sass sözdizimini destekler
Sass sözdizimini, herhangi bir önişlemci veya ekstra derleme aracı kurmak zorunda kalmadan kutudan çıkar çıkmaz stil bileşenleriyle yazmak mümkündür. Stil tanımlarınızda, geçerli bileşeni hedeflemek için&
karakterini kullanabilir, sözde seçiciler kullanabilir ve iç içe yerleştirmeyi deneyebilirsiniz. - Temalandırma
tarz bileşenleri, birThemeProvider
sarmalayıcı bileşenini dışa aktararak tam tema desteğine sahiptir. Bu bileşen, Context API aracılığıyla kendi içindeki tüm React bileşenlerine bir tema sağlar. Oluşturma ağacında, tüm stil bileşenlerinin, birden çok düzeyde derin olsalar bile sağlanan temaya erişimi olacaktır. Bu öğreticide devam ederken, stil bileşenlerinin tema özelliklerine daha derinlemesine bakacağız.
Tarz bileşenlerinin daha fazla avantajını öğrenmek için Kris Guzman'ın makalesine göz atın.
Karanlık Modu Uygulama
Bu yazımızda YouTube benzeri basit bir web sayfasında karanlık modu uygulayacağız.
Devam etmek için, orijinal depoyu starter
dalından klonladığınızdan emin olun.
Kurulum
package.json
dosyamızdaki tüm bağımlılıkları yükleyelim. Terminalden aşağıdaki komutu çalıştırın:
npm install
Başarılı kurulumunun ardından npm start
. İşte karanlık mod uygulanmadan web sayfası böyle görünüyor.
styled-components
yüklemek için terminalinizde npm install styled-components
çalıştırın.
uygulama
Karanlık modu uygulamak için dört farklı bileşen oluşturmamız gerekiyor.
-
Theme
Bu, açık ve koyu temalarımızın renk özelliklerini içerir. -
GlobalStyles
Bu, tüm belge için genel stilleri içerir. -
Toggler
Bu, işlevselliği değiştiren düğme öğesini tutar. -
useDarkMode
Bu özel kanca, tema değişikliğinin arkasındaki mantığı ve temamızın localStorage'daki kalıcılığını ele alır.
Tema Bileşeni
src
klasöründe, components
klasöründe bileşenleri göreceksiniz. Bir Themes.js
dosyası oluşturun ve buna aşağıdaki kodu ekleyin.
export const lightTheme = { body: '#FFF', text: '#363537', toggleBorder: '#FFF', background: '#363537', } export const darkTheme = { body: '#363537', text: '#FAFAFA', toggleBorder: '#6B8096', background: '#999', }
Burada lightTheme
ve darkTheme
nesnelerini farklı renk değişkenleriyle tanımladık ve dışa aktardık. Değişkenleri size uyacak şekilde denemekten ve özelleştirmekten çekinmeyin.
globalStyles Bileşeni
components
klasörünüzde kalan bir globalStyles.js
dosyası oluşturun ve aşağıdaki kodu ekleyin:
import { createGlobalStyle} from "styled-components" export const GlobalStyles = createGlobalStyle` body { background: ${({ theme }) => theme.body}; color: ${({ theme }) => theme.text}; font-family: Tahoma, Helvetica, Arial, Roboto, sans-serif; transition: all 0.50s linear; } `
Stil bileşenlerinden createGlobalStyle
içe aktardık. createGlobalStyle
yöntemi, styled-components sürüm 3'ten artık kullanımdan kaldırılan injectGlobal yönteminin yerini alır. Bu yöntem, bileşen ağacınıza eklendiğinde belgeye global stilleri, bizim durumumuzda App.js
olan bir React bileşeni oluşturur.
Bir GlobalStyle
bileşeni tanımladık ve tema nesnesindeki değerlere background
ve color
özellikleri atadık. Böylece, toggle'ı her değiştirdiğimizde, ThemeProvider
(daha sonra oluşturulacak olan) ilettiğimiz karanlık temaya veya açık tema nesnelerine bağlı olarak değerler değişecektir.
0.50s
geçiş özelliği, bu değişikliğin biraz daha düzgün olmasını sağlar, böylece ileri geri geçiş yaptıkça, değişikliklerin gerçekleştiğini görebiliriz.
Tema Değiştirme İşlevselliği Oluşturma
Tema değiştirme işlevini uygulamak için yalnızca birkaç satır kod eklememiz gerekiyor. App.js
dosyasına aşağıdaki kodu ekleyin (vurgulanan kodun eklemeniz gerektiğini unutmayın):
import React, { useState, useEffect } from "react";
import {ThemeProvider} from "styled-components"; import { GlobalStyles } from "./components/Globalstyle"; import { lightTheme, darkTheme } from "./components/Themes"
import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]);
const [theme, setTheme] = useState('light'); const themeToggler = () => { theme === 'light' ? setTheme('dark') : setTheme('light') }
useEffect(() => { const timer = setTimeout(() => { setVideos(dummyData); }, 1000); return () => clearTimeout(timer); }, []); return (
<ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme}> <> <GlobalStyles/>
<div className="App">
<button onClick={themeToggler}>Switch Theme</button>
{ videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div>
</> </ThemeProvider>
); }; export default App;
Vurgulanan kod, App.js
yeni eklenen koddur. ThemeProvider
styled-components
içe aktardık. ThemeProvider
, stil bileşenleri kitaplığında tema desteği sağlayan yardımcı bir bileşendir. Bu yardımcı bileşen, Context API aracılığıyla kendi altındaki tüm React bileşenlerine bir tema enjekte eder.
Oluşturma ağacında, tüm stil bileşenlerinin, birden çok düzeyde derin olsalar bile sağlanan temaya erişimi olacaktır. “Tema” bölümüne bakın.
Ardından, GlobalStyle
sarmalayıcısını ./components/Globalstyle
içe aktarıyoruz. Son olarak, üstten hem lightTheme
hem de darkTheme
nesnelerini ./components/Themes
öğesinden içe aktarıyoruz.
Bir geçiş yöntemi oluşturabilmemiz için temamızın başlangıç renk değerini tutan bir duruma ihtiyacımız var. Böylece, bir theme
durumu oluşturuyoruz ve useState
kancasını kullanarak ilk durumu light
olarak ayarlıyoruz.
Şimdi, geçiş işlevi için.
themeToggler
yöntemi, theme
durumunu kontrol etmek için üçlü bir operatör kullanır ve koşulun değerine göre koyu veya açık arasında geçiş yapar.
Tarz bileşenleri yardımcı bileşeni olan ThemeProvider
, return
ifadesindeki her şeyi sarar ve altındaki tüm bileşenleri enjekte eder. GlobalStyles
bileşenlerimize global stiller eklediğini unutmayın; bu nedenle, ThemeProvider
sarmalayıcı bileşeninin içinde çağrılır.
Son olarak, ona themeToggler
yöntemimizi atayan bir onClick
olayıyla bir düğme oluşturduk.
Şimdiye kadarki sonuca bakalım.
App.js
dosyamızın yeniden düzenlenmesi gerekiyor; kodunun çoğu DRY değildir. (DRY, tekrarı azaltmayı amaçlayan yazılım geliştirmenin temel bir ilkesi olan “kendini tekrar etme” anlamına gelir.) Tüm mantık App.js
görünüyor; Açıklık sağlamak için mantığımızı ayırmak iyi bir uygulamadır. Bu nedenle, geçiş işlevselliğini işleyen bir bileşen oluşturacağız.
Bileşeni Değiştir
Yine de components
klasörü içinde bir Toggler.js
dosyası oluşturun ve ona aşağıdaki kodu ekleyin:
import React from 'react' import { func, string } from 'prop-types'; import styled from "styled-components" const Button = styled.button` background: ${({ theme }) => theme.background}; border: 2px solid ${({ theme }) => theme.toggleBorder}; color: ${({ theme }) => theme.text}; border-radius: 30px; cursor: pointer; font-size:0.8rem; padding: 0.6rem; } \`; const Toggle = ({theme, toggleTheme }) => { return ( <Button onClick={toggleTheme} > Switch Theme </Button> ); }; Toggle.propTypes = { theme: string.isRequired, toggleTheme: func.isRequired, } export default Toggle;
İşleri düzenli tutmak için, stiller bileşenlerindeki styled
işlevini kullanarak Toggle
bileşenindeki geçiş düğmemizi biçimlendirdik.
Bu tamamen tanıtım amaçlıdır; düğmeyi uygun gördüğünüz gibi şekillendirebilirsiniz.
Toggle
bileşeninin içinde iki props geçiyoruz:
-
theme
mevcut temayı sağlar (açık veya koyu); - temalar arasında geçiş yapmak için
toggleTheme
işlevi kullanılacaktır.
Ardından, Button
bileşenini döndürdük ve onClick
olayına bir toggleTheme
işlevi atadık.
Son olarak, türlerimizi tanımlamak için propTypes
kullanırız, theme
bir string
ve isRequired
sağlarken toggleTheme
func
ve isRequired
.
Özel Kancaları Kullanma ( useDarkMode
)
Bir uygulama oluştururken ölçeklenebilirlik çok önemlidir, yani iş mantığımızın yeniden kullanılabilir olması gerekir, böylece onu birçok yerde ve hatta farklı projelerde kullanabiliriz.
Bu nedenle, geçiş işlevimizi ayrı bir bileşene taşımak harika olurdu. Bunun için kendi özel kancamızı yaratırdık.
components
klasöründe useDarkMode.js
adında yeni bir dosya oluşturalım ve bazı tweaks ile mantığımızı bu dosyaya taşıyalım. Dosyaya aşağıdaki kodu ekleyin:
import { useEffect, useState } from 'react'; export const useDarkMode = () => { const [theme, setTheme] = useState('light'); const setMode = mode => { window.localStorage.setItem('theme', mode) setTheme(mode) }; const themeToggler = () => { theme === 'light' ? setMode('dark') : setMode('light') }; useEffect(() => { const localTheme = window.localStorage.getItem('theme'); localTheme && setTheme(localTheme) }, []); return [theme, themeToggler] };
Buraya birkaç şey ekledik.
-
setMode
Tarayıcıdaki oturumlar arasında kalıcı olmak içinlocalStorage
kullanıyoruz. Bu nedenle, bir kullanıcı koyu veya açık temayı seçtiyse, uygulamayı bir sonraki ziyaretlerinde veya sayfayı yeniden yüklediğinde elde edecekleri şey budur. Bu nedenle, bu işlev durumumuzu belirler vetheme
localStorage
. -
themeToggler
Bu işlev, temanın durumunu kontrol etmek için üçlü bir operatör kullanır ve koşulun gerçekliğine göre koyu veya açık arasında geçiş yapar. -
useEffect
Bileşen montajını kontrol etmek içinuseEffect
kancasını uyguladık. Kullanıcı daha önce bir tema seçmişse onusetTheme
fonksiyonumuza geçireceğiz. Sonunda, seçilentheme
ve modlar arasında geçiş yapmak içinthemeToggler
işlevini içerentheme
döndüreceğiz.
Karanlık mod bileşenimizin şık göründüğü konusunda hemfikirsiniz.
Son dokunuşlar için App.js
gidelim.
import React, { useState, useEffect } from "react"; import {ThemeProvider} from "styled-components";
import {useDarkMode} from "./components/useDarkMode"
import { GlobalStyles } from "./components/Globalstyle"; import { lightTheme, darkTheme } from "./components/Themes" import Toggle from "./components/Toggler" import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]);
const [theme, themeToggler] = useDarkMode(); const themeMode = theme === 'light' ? lightTheme : darkTheme;
useEffect(() => { const timer = setTimeout(() => { setVideos(dummyData); }, 1000); return () => clearTimeout(timer); }, []); return (
<ThemeProvider theme={themeMode}>
<> <GlobalStyles/> <div className="App">
<Toggle theme={theme} toggleTheme={themeToggler} />
{ videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div> </> </ThemeProvider> ); }; export default App;
Vurgulanan kod App.js
yeni eklendi.
İlk olarak, özel kancamızı içe aktarıyoruz, theme
ve themeToggler
aksesuarlarını yok ediyoruz ve onu useDarkMode
işleviyle ayarlıyoruz.
useDarkMode
yönteminin, başlangıçta App.js
olan theme
durumumuzun yerini aldığını unutmayın.
O sırada theme
modunun durumuna bağlı olarak açık veya koyu bir tema oluşturan bir themeMode
değişkeni bildiririz.
Şimdi, ThemeProvider
sarmalayıcı bileşenimiz, yakın zamanda oluşturulan themeMode
değişkenimize theme
prop'una atanmıştır.
Ve son olarak normal buton yerine Toggle
bileşenini geçiyoruz.
Toggle
bileşenimizde bir düğme tanımlayıp stilini belirlediğimizi ve hem theme
hem de toggleTheme
onlara sahne olarak ilettiğimizi unutmayın. Bu nedenle, tek yapmamız gereken bu aksesuarları App.js
olarak işlev görecek olan Toggle
bileşenine uygun şekilde geçirmek.
Evet! Karanlık modumuz ayarlandı ve sayfa yenilendiğinde veya yeni bir sekmede ziyaret edildiğinde renk değiştirmeden devam ediyor.
Eylemdeki sonucu görelim:
Neredeyse her şey yolunda gidiyor, ancak deneyimimizi muhteşem kılmak için yapabileceğimiz küçük bir şey var. Karanlık temaya geçin ve ardından sayfayı yeniden yükleyin. Düğmedeki mavi rengin kısa bir an için griden önce yüklendiğini görüyor musunuz? Bunun nedeni, useState
başlangıçta light
temasını başlatmasıdır. Bundan sonra useEffect
çalışır, localStorage
öğesini kontrol eder ve ancak bundan sonra theme
dark
olarak ayarlar. Özel useDarkMode.js
ve küçük bir kod ekleyelim:
import { useEffect, useState } from 'react'; export const useDarkMode = () => { const [theme, setTheme] = useState('light');
const [mountedComponent, setMountedComponent] = useState(false)
const setMode = mode => { window.localStorage.setItem('theme', mode) setTheme(mode) }; const themeToggler = () => { theme === 'light' ? setMode('dark') : setMode('light') }; useEffect(() => { const localTheme = window.localStorage.getItem('theme'); localTheme ? setTheme(localTheme) : setMode('light')
setMountedComponent(true)
}, []); return [theme, themeToggler,
}, []); return [theme, themeToggler,
mountedComponent
]
};
Vurgulanan kod, useDarkMode.js
eklenen tek koddur. mountedComponent
adında başka bir durum yarattık ve useState
kancasını kullanarak varsayılan değeri false
olarak ayarladık. Ardından, useEffect
kancasının içinde, setMountedComponent kullanarak mountedComponent
durumunu true
olarak setMountedComponent
. Son olarak, return
dizisinde mountedComponent
durumunu ekliyoruz.
Son olarak, hepsinin çalışması için App.js
biraz kod ekleyelim.
import React, { useState, useEffect } from "react"; import {ThemeProvider} from "styled-components"; import {useDarkMode} from "./components/useDarkMode" import { GlobalStyles } from "./components/Globalstyle"; import { lightTheme, darkTheme } from "./components/Themes" import Toggle from "./components/Toggler" import "./App.css"; import dummyData from "./data"; import CardList from "./components/CardList"; const App = () => { const [videos, setVideos] = useState([]);
const [theme, themeToggler, mountedComponent] = useDarkMode();
const themeMode = theme === 'light' ? lightTheme : darkTheme; useEffect(() => { const timer = setTimeout(() => { setVideos(dummyData); }, 1000); return () => clearTimeout(timer); }, []);
if(!mountedComponent) return <div/>
return ( <ThemeProvider theme={themeMode}> <> <GlobalStyles/> <div className="App"> <Toggle theme={theme} toggleTheme={themeToggler} /> { videos.map((list, index) => { return ( <section key={index}> <h2 className="section-title">{list.section}</h2> <CardList list={list} /> <hr /> </section> ); })} </div> </> </ThemeProvider> ); }; export default App;
mountComponent durumumuzu mountedComponent
bir destek olarak ekledik ve bileşenimizin takılı olup olmadığını kontrol ettik, çünkü useDarkMode
kancasında olan useEffect
. Henüz olmadıysa, boş bir div
oluşturacağız.
Karanlık mod web sayfamızın sonucunu görelim.
Şimdi, karanlık moddayken sayfa yeniden yüklendiğinde düğmenin renginin değişmediğini fark edeceksiniz.
Çözüm
Karanlık mod giderek bir kullanıcı tercihi haline geliyor ve bunu bir React web uygulamasında uygulamak, ThemeProvider
tema sarmalayıcısını stil bileşenlerinde kullanırken çok daha kolay. Devam edin ve karanlık modu uygularken tarz bileşenleriyle denemeler yapın; bir düğme yerine simgeler ekleyebilirsiniz.
Lütfen aşağıdaki yorumlar bölümünde stil bileşenlerindeki tema özelliğiyle ilgili geri bildiriminizi ve deneyiminizi paylaşın. Ne bulduğunu görmek isterim!
Bu makalenin destekleyici deposu GitHub'da mevcuttur. Ayrıca CodeSandbox'ta kontrol edin.
Referanslar
- "Belgeleme", stil bileşenleri
- "Tarzlanmış Bileşenleri kullanarak uygulamanızın Karanlık Modunu oluşturun", Tom Nolan, Medium