3 dk, tahmini okuma süresi
Fonksinel bileşenler (fucntional components) kesinlikle benim en sevdiğim react bileşeni türü. Bu bileşenleri oluşturmayı ve okumayı çok daha kolay buluyorum. Bileşeni çalışır duruma getirmek için gereken minimum standart kod boyutu da alternatiften çok daha küçüktür. React Hookları (Kancalar), fonksiyonel bileşenlerle çalışırken en büyük yardımcınız olacak.
Using this hook makes dealing with state in react so easy. Going through setState in class based components is also easy to create but not as easy and straight-forward as using a hook. This hook can be initialized with a state.
Bu hooku kullanmak, react.js'te state ile uğraşmayı çok kolaylaştıyor. Sınıf tabanlı bileşenlerde setState'i oluşturmak da kolaydır, ancak bir hook kullanmak kadar kolay ve basit değil. Bu hook bir başlangıç değeri kullanılarak da oluşturulabilir.
const [data, setData] = useState(0);
state'i ayarlamak için setState'i şu şekilde kullanacağız:
setState(newState);
State'i dinamik olarak şu şekilde ayarlayabiliriz:
const NameChanger = ({name}) => {
const [name, setName] = useState(name);
return (
<>
Count: {name}
<button onClick={() => setName(name)}>Reset Name</button>
<button onClick={() => setName("Slim Shady")}>Slim Shady</button>
<button onClick={() => setName("Giovanna Giorno")}>Giovanna Giorno</button>
</>
);
}
"name" değerini ayarlıyoruz ve sıfırlama (reset) düğmesi, name'e ilk değerini tekrar verecektir. Çok basit ve okunması kolay değil mi? Mevcut değeri kullanarak state değerini manipüle etmek de çok kolaydır. Bu butonu bileşenimize eklemek, bunu yapmamıza yardımcı olacaktır:
<button onClick={() => setName(prevName => prevName + "!")}>Add "!"</button>
Bu buton ile sadece name'in sonuna "!" ekliyoruz. prevName sınıf tabanlı bileşenlerde olduğu gibi, eski değere kullanrak yeni değeri oluşturmamıza yardımcı oluyor.
setState(prevState => {
// Object.assign da burada kullanılabilirdi
return {...prevState, ...updatedValues};
});
Well there we go, in my opinion this was actually 60% of what react is all about. If you have learned something from this part, good job!
İşte bu kadar! Buraya kadar olan kısım aslında bana kalırsa react.js'in 60%'ını oluşturuyor. Bu iki kısımla akalaı önceden bilmediğiniz bir şey öğrendiyseniz tebrikler.
Bu hook, componentDidMount, componentDidUpdate ve componentWillUnmount'un eşdeğeridir.
We handle subscriptions, timers, mutations, logging and side effects are supposed to be handled here using this hook. Side effect clean up is done in our return statement. An example will work better I guess:
Abonelikleri, zamanlayıcıları, mutasyonları, günlüğe kaydetmeyi (logging) ve yan etkilerin bu kancayı kullanarak burada ele alınması gerekiyor. Yan etki temizliği return ifademizde yapılır. Bir örnek daha açıklayıcı olacak sanırım:
useEffect(() => {
const interval = setInterval(() => {
console.log('Bu her saniye çalışacak!');
}, 1000);
return () => clearInterval(interval);
}, []);
interval return ifademizde kullanılarak kolayca temizleniyor. Aksi taktirde üstüste binecek ve olması gerekenden daha fazla console.log goreceksiniz. clearInterval() ile bu temizliği yapıyoruz.
We can define a condition for firing up our useEffect. useEffect waits for the change in our conditions array and fires up when the condition changes:
useEffect'imizi başlatmak için bir koşul tanımlayabiliriz. useEffect, koşullar arrayimizde oluşacak değişikliği bekler ve koşul değiştiğinde tetiklenir:
useEffect(() => {
console.log("koşul değişti")
}, [koşul])
İstediğiniz kadar useEffect oluşturabilirsiniz. Rolleri veya işlevleri ne olursa olsun.
React Context API, büyük projelerde durum yönetimi söz konusu olduğunda tam bir cankurtarandır. Context API'yi redux'un alternatifi olarak düşünebilirsiniz. Bu hook ile state'e ulaşabilir ve react projelerinizde bir kullanıcı veya tutarlı bir tema sağlayabilirsiniz.
We return the current context value for our specific context (MyContext) this way:
Belirli bir context değerini (MyContext) şu şekilde geri getiriyoruz:
const value = useContext(MyContext);
Bileşenin üzerindeki en yakın js <MyContext.Provider> öğesini bir şekilde güncellerseniz, bu Hook, o MyContext'e iletilen en son bağlam değeriyle bir yeniden oluşturmayı (re-render) tetikler.
React dökümanlarında verilen örneği doğrudan kopyalıyorum. Kullanımını açıklayabilecek daha iyi bir örnek bulamadım.
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}
Dinamik olarak değişmesi gereken bir içerikle ilgili bir sorununuz oldu mu ve kullanıcıya görmemeleri gereken bir şeyi bir anlığına da olsa gösteriyor muydunuz? Cevabınız evet ise, bu, sorununuzu çözecek olan hooktur.
useEffect ve useLayoutEffect arasında yalnızca bir fark var, useLayoutEffect tüm DOM mutasyonlarından sonra eşzamanlı olarak tetiklenir. useLayoutEffect içinde planlanan güncellemeler, tarayıcının boyama (paint) şansı bulamadan eşzamanlı olarak temizlenecektir. DOM'umuzdaki o korkunç içerik akışlarını önlemek için bu kancayı kullanmak isteyeceksiniz.
Sınıf tabanlı bileşenleri kullanmaya daha alışkınsanız, bu Hook'u componentDidMount ve componentDidUpdate'in eşdeğeri olarak düşünün.
Sunucu oluşturmada react, useLayoutEffect kullandığınızda sizi uyarır. Çünkü useLayoutEffect Javascript indirilene kadar çalışamaz.
useLayoutEffect'in useEffect'ten biraz daha zor olduğunu unutmayın. Değiştirilebilir olduğunda useEffect kullanın. Zaten çoğu zaman useEffect'e ihtiyacınız olacak.
Bu hooku swr paketini kurarak alabilirsiniz.
npm i swr
Bu Kancayı, react.js'de önbelleğe almayı kolayca işlemenin düzgün bir yolu olarak düşünün. "SWR" adı, "stale-while-revalidate" kelimelerinden türemiştir. SWR önce verileri önbellekten (stale) döndürür, ardından isteği gönderir (revalidate) ve son olarak tekrar güncel verilerle birlikte gelir. Dökümanları buradan okuyabilirsiniz.
import useSWR from 'swr'
function Profile() {
const { data, error } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
This hook takes two arguments. The "key" and the "fetcher" function. The key will be used as a unique identifier and the fetcher will return data and error objects. Key is usually the url of the API we would like to use.
Bu kanca iki argüman alır. "key" değeri ve "fetcher" fonksiyonu. Key, benzersiz bir tanımlayıcı olarak kullanılacak ve fetcher, verileri ve hata nesnelerini döndürecektir. Key genellikle kullanmak istediğimiz API'nin URL'sidir.
"data" value is undefined until the request is finished. When it finishes it's either data or error.
"data" değeri, istek bitene kadar tanımsızdır. Bittiğinde ya veridir (data) ya da hatadır (error).
Belgelerden basit bir örnek:
import useSWR from 'swr'
function Profile() {
const { data, error } = useSWR('/api/user', fetcher)
if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}
Bu özel Hook için birçok kullanım alanı ve durumu var.
useRef bir değerle başlatılabilir:
const refContainer = useRef(baslangic);
This is another example to its usage. The value will persist between re-renders cause by state changes. So you could keep a count in this manner by using this hook.
Bu, kullanımına başka bir örnektir. Değer, state değişikliklerinin neden olduğu yeniden oluşturmalar arasında devam edecek ve korunacaktır. Böylece bu kancayı kullanarak bu şekilde bir count (sayım) değeri tutabilirsiniz.
const MyComponent = () => {
const ref = useRef({
count: 0
});
// her yeniden oluşturma, sayının bir artmasına neden olur
ref.current.count += 1;
// bu yöntemi kullanarak da sayımı artırabilirsiniz.
const incrementCount = () => {
ref.current.count += 1;
}
return <>Hello world</>;
}
Bu değer, durum değişikliklerinden ve yeniden oluşturma işlemlerinden sonra tutulacaktır. Eminim bu hook'un işe yarayabileceği birkaç senaryo düşünebilirsiniz.
useRef Hook genellikle bir çocuğa (child) erişmek için kullanılır:
function TextInputWithFocusButton() {
const inputEl = useRef(null);
const onButtonClick = () => {
inputEl.current.focus();
};
return (
<>
<input ref={inputEl} type="text" />
<button onClick={onButtonClick}>Focus the input</button>
</>
);
}
Bu şekilde butona tıklamak doğrudan input'a odaklanmamızı sağlayacaktır. Bu odak (focus) yöntemini bir useEffect Hook'ta kullanabilirsiniz ve sayfanız açıldığında yazılmaya hazır bir formunuz olur.
Ilker Akbiyik