useState kancası - Kapsamlı bir kılavuz

useState kancası – Kapsamlı bir kılavuz

Kaynak Düğüm: 1780723

Devlet nedir?

useState kancasına derinlemesine dalmadan önce, önce terimi anlayalım. devlet.

Durum, belirli bir zamanda bir şey hakkındaki bilgileri temsil eder.

Örneğin, bir metin kutusu düşünelim.

Başlangıçta, bu metin kutusunun içinde hiçbir şey yoktur, bu nedenle durumu boş. İçine Hello yazmaya başladığınızı varsayalım, her tuş vuruşu için metin kutusunun durumu değişecektir. İlk başta “H”, sonra “He”, ardından “Hel” ve “Merhaba” olana kadar böyle devam eder.

Ayrıca, yazarken önceki değeri kaybetmediğinize dikkat edin. “H”ye ve ardından “e”ye basarsanız, sadece “e” değil, “He” alırsınız. Başka bir deyişle, durumu devlet olarak düşünebilirsiniz. bellek metin kutusundan.

Bir React bileşeninde durum ihtiyacı.

Bunu bir örnek yardımıyla anlayalım.

Durumsuz Codesanbox

Burada bir Tıklama Sayacı Artırma düğmesinin tıklanma sayısını gösteren bileşen.

Biz kullanıyoruz yerel değişken "sayaç" tıklama sayısını tutmak için.

Arttır düğmesine her tıkladığımızda, tutamaçtıklama fonksiyon çağrılır. Bu işlev, sayaç değerini 1 artıracak ve ayrıca değeri konsolda günlüğe kaydedecektir.

Devam edin, CodeSandbox önizlemesinde Artırma düğmesini tıklayın.

Hiçbir şey olmadı?

Peki, mantığımız doğru görünüyor. Konsolda (CodeSandbox) günlüğe kaydedilen değer, her tıkladığımızda doğru şekilde güncelleniyor, ancak bu güncelleme neden kullanıcı arayüzüne yansıtılmıyor?

Bunun nedeni React'in çalışma şeklidir.

  • Yerel değişkenlerde yapılan değişiklikler yeniden oluşturmayı tetiklemez.
  • Yeniden oluşturma sırasında, sıfırdan bir bileşen oluşturulur, yani bir bileşenin işlevi (bu örnekte bu ClickCounter işlevidir) bir kez daha yürütülür. Değişkenler (örneğin sayaç) fonksiyon için yerel olduğundan önceki değerleri kaybolur.

Peki, bileşenin oluşturmalar arasındaki değerleri hatırlamasını nasıl sağlarız?

Gif bir cevaba geliyor

Evet, doğru anladın! yardımıyla bunu yapıyoruz. Kullanım Durumu kancası.

useState kancası

useState kancası, durumu korumak ve yeniden oluşturmayı tetiklemek için mekanizmalar sağlar.

kullanımına bakalım.

import React, { useState } from "react";
const state = useState(initialValue); // OR const state = React.useState(initialValue);

useState kancası, iki öğe içeren bir dizi döndürür:

  • A durum değişkeni yeniden oluşturma sırasında değerlerini korur. useState öğesine iletilen ilk değer, ilk oluşturma sırasında durum değişkenine atanır.
  • A ayarlayıcı işlevi durum değişkenini günceller ve ayrıca yeniden oluşturmayı tetikler.
const state = useState(0);
const data = state[0];
const setData = state[1];

kullanma dizi yapısını bozma , yukarıdaki ifadeleri aşağıda gösterildiği gibi tek bir ifadeye dönüştürebiliriz:

const [data, setData] = useState(0);

useState'e iletilen ilk değer yalnızca ilk oluşturma sırasında kullanılır. Yeniden işlemeler için yoksayılır.

useState ile sayaç

Şimdi, önceki sayaç örneğini useState kancasını içerecek şekilde güncelleyelim.

  • Yeniden oluşturmalar arasında sayaç değerine ihtiyacımız olduğundan, onu bir duruma dönüştürelim.
const [counter, setCounter] = useState(0);
  • HandleClick işlevi içinde setCounter çağrılıyor.
const handleClick = () => { setCounter(counter + 1); console.log(`%c Counter:${counter}`, "color:green");
};

setCounter işlevi, sayaç değerini 1 günceller ve yeniden oluşturmayı tetikler. Yeniden oluşturma sırasında bileşenin işlevi çağrıldığında, useState tarafından döndürülen durum değişkeni güncellenmiş değere sahip olacaktır.

Güncellenmiş kodla CodeSandbox'ı deneyin. Arttır düğmesini tıklayın ve useState büyüsünü iş başında görün.

useState ile Codesanbox

Yeniden oluşturmada, işlevsel bileşenin olduğunu doğrulayabilirsiniz. Tıklama Sayacı konsol günlüklerini görüntüleyerek tekrar çağrılır. Bileşenin başına eklenen “ClickCounter start” günlüğü her işlemede günlüğe kaydedilecektir.

ilk render

yeniden işlemek

güncelleyici işlevi

Her tıklamada sayacın değerini 4 artırmak istediğimizi varsayalım.

const handleClick = () => { setCounter(counter + 1); setCounter(counter + 1); setCounter(counter + 1); setCounter(counter + 1); console.log(`%c Counter:${counter}`, "color:green"); };

Sayacın başlangıç ​​değerinin 0 olduğunu varsayın. Düğmeye tıklandığında ne görmeyi umuyorsunuz?

Güncelleyici işlevi olmadan

Sayının 4 olmasını bekliyordun değil mi? Ama neden bunun yerine 1 görüyorsunuz?

a) Her render bir durumla ilişkilendirilir. Bu durumun değeri, o oluşturmanın ömrü boyunca kilitli kalır.

HandleClick işlevinin içindeki günlüğün sayaç değerini 0 olarak yazdırdığına dikkat edin.

setCounter yöntemini kaç kez çağırırsanız çağırın sayacın değeri aynı kalır.

const handleClick = () => { setCounter(counter + 1); setCounter(counter + 1); setCounter(counter + 1); setCounter(counter + 1); console.log(`%c Counter:${counter}`, "color:green"); };
b) Bir olay işleyicisinin içindeki tüm kod çalıştırılana kadar, React yeniden oluşturma işlemini tetiklemeyecektir.

Bu nedenle her setCounter çağrısı bireysel bir oluşturma işlemini tetiklemez. Bunun yerine React, bu ayarlayıcı işlevlerini bir kuyruğa ekler. Bunları kuyruğa alındıkları sırayla yürütür. Tüm ifadeler yürütüldükten sonra duruma yapılan güncellemeler bir sonraki render'a yansıtılır. Birden çok durum güncellemesinin bu kuyruğa alınması şu şekilde bilinir: harmanlama. React'in daha performanslı olmasını sağlar.

Dolayısıyla burada 4 farklı render yerine tek bir render alıyoruz.

Bu örnek basittir ve kodu aşağıda gösterildiği gibi güncelleyerek bu sorunu çözebilirsiniz:

const handleClick = () => {
setCounter(counter + 4); console.log(`%c Counter:${counter}`, "color:green"); };

Ancak, bir sonraki oluşturma işleminden önce durumu birden çok kez güncellemek istediğiniz bir kullanım durumunuz varsa ne olur?

_ güncelleyici _ işlevi işe yarar.

Güncelleyici işleviyle önceki örneği aşağıdaki gibi yeniden düzenleyebiliriz:

const handleClick = () => { setCounter(prevCounter => prevCounter + 1); setCounter(prevCounter => prevCounter + 1); setCounter(prevCounter => prevCounter + 1); setCounter(prevCounter => prevCounter + 1); console.log(`%c Counter:${counter}`, "color:green"); };

İşte öncekiSayaç ⇒ öncekiSayaç + 1 güncelleyici işlevini temsil eder.

Daha önce açıklandığı gibi, bu güncelleyici ifadeleri de kuyruğa alınır (toplama).

Güncelleyici işlevi, bir sonraki durumu hesaplamak için kullandığı bir bekleyen/önceki durumu alır.

Güncelleyici işlevi gruplaması

Güncelleyici işlevi eklenmiş CodeSandbox aşağıdadır. Arttırma düğmesine tıklamayı deneyin.

Güncelleyici işlevi sanal alanı

Başlatıcı işlevi

Aşağıdaki örneğe bir göz atın. Burada durum için başlangıç ​​değerini almak için getItems işlevini çağırıyoruz.

import React from "react";
import { useState } from "react";
function ListItems() { const getItems = () => { console.log(`%c getItems called`, "color:hotpink"); return Array(50).fill(0); }; const [items, setItems] = useState(getItems()); return ( <div className="card"> <ul> {items.map((item, index) => ( <li key={index}>Item {index + 1} </li>))} </ul> <button onClick={() => setItems([...items, 0])}>Add Item</button> </div> );
} export default ListItems;

Bu işlev, boyutu 50 olan bir dizi oluşturur ve diziyi sıfırlarla doldurur. Aşağıdaki resme bakın.

50 sıfırla dolu dizi

Bu öğeler daha sonra ekranda görüntülenir.

Her şey yolunda görünüyor ama burada bir sorunumuz var.

Tıkla Öğe eklemek Listeye yeni bir öğe eklemek için (öğe listesinden sonra bulunur) düğmesine basın. Günlükleri gözlemleyin.

Başlatıcı işlevi olmadan

Buradaki problemi görüyor musun?

Her öğe eklediğinizde "getItems çağrıldı" günlüğü konsola eklenir. Bu, bu işlevin her işlemede çağrıldığı anlamına gelir.

useState'in ilk oluşturmadan sonra kendisine iletilen ilk değeri yok saydığını, ancak burada ilk değerin hala yeniden hesaplandığını unutmayın. Büyük diziler oluşturuyorsak veya ağır hesaplamalar yapıyorsak bu pahalı olabilir.

Geçerek bu sorunu çözebiliriz Öğeleri al _ olarak başlatıcı _ işlev.

Şimdi kodda küçük bir değişiklik yapalım.

const [items, setItems] = useState(getItems);

Başlatıcı işlevi ile

CodeSandbox'taki konsol penceresine bakın. "getItems denilen" günlüğünün yalnızca ilk işlemede yazdırıldığına dikkat edin. Sonraki öğeler eklendiğinde bu günlük yok.

İki örnek arasında görsel bir fark olmamasına rağmen performans açısından farklıdırlar.

İlk durum için bir fonksiyona ihtiyacınız olduğunda, daima fonksiyonu iletin veya fonksiyonu başka bir fonksiyonun içinde çağırın. Fonksiyonu asla doğrudan çağırmayın.

✅ const [items, setItems] = useState(getItems);
✅ const [items, setItems] = useState(() => getItems());
❌ const [items, setItems] = useState(getItems());

Kaç useState kancam olabilir

Bir bileşenin içinde gerektiği kadar useState kancanız olabilir.

CodeSandbox'a bakın

Çoklu useState kancaları

Aşağıdaki bileşenin üç farklı durumu vardır – kullanıcı adı, parola, keepMeSignedIn.

KeepMeSignedIn adlı kullanıcı adının değerlerini güncellemeyi deneyin. Oturum açma düğmesine tıklandığında güncellenen durumlar konsola kaydedilir.

Özeti

  • useState, yeniden oluşturmayı tetiklemek ve durumu yeniden oluşturmalar arasında sürdürmek için bir mekanizma sağlar.
  • Aşağıdakileri yapmanız gerektiğinde güncelleyici işlevini kullanın:
    • Önceki duruma göre sonraki durumu hesaplayın.
    • Bir sonraki oluşturma işleminden önce durum için birden çok güncelleme yapın.
  • Bir işlevden başlangıç ​​durumu elde edilirse, başlatıcı işlevi sözdizimini kullanın.
  • Bir bileşenin içinde birden çok useState kancası olabilir.

Bu gönderiyi beğendiniz mi? Başkalarıyla paylaşın.
Orijinal olarak kişisel blogum için yazılmış - https://gauravsen.com/use-state-hook

Zaman Damgası:

Den fazla Codementor Tepki Gerçeği