React Hooks'ta (useState) itme yöntemi?


Yanıtlar:


270

Kullandığınızda useState, durum öğesi için bir güncelleme yöntemi alabilirsiniz:

const [theArray, setTheArray] = useState(initialArray);

sonra, yeni bir öğe eklemek istediğinizde, bu işlevi kullanır ve yeni diziyi veya yeni diziyi yaratacak bir işlevi iletirsiniz. Durum güncellemeleri eşzamansız olduğundan ve bazen toplu işlendiğinden, normalde ikincisi:

setTheArray(oldArray => [...oldArray, newElement]);

Bazen , işleyicilerdeki diziyi yalnızca aşağıdakiler gibi click(ancak beğenmeyeceğiniz mousemove) belirli belirli kullanıcı olayları için güncellerseniz , bu geri arama formunu kullanmadan kurtulabilirsiniz :

setTheArray([...theArray, newElement]);

React'in oluşturmanın temizlendiğinden emin olduğu olaylar, burada listelenen "ayrı olaylar" dır .

Canlı Örnek (geri aramayı şuraya iletme setTheArray):

theArrayBuradaki tek güncelleme, clickolaydaki bir güncelleme olduğu için ("ayrı" olaylardan biri), şu konularda doğrudan güncelleme yapabilirim addEntry:


1
... ve setTheArray(currentArray => [...currentArray, newElement])yukarıdakilerin işe yaramazsa deneyin . Büyük olasılıkla useEffect(...theArray..., []), bunun theArraysürekli olduğunu anlamak önemlidir , bu nedenle gelecekteki
renderlardan

@Aprillion - Bu örnekle ne söylediğinden tam olarak emin değilim useEffect...?
TJ Crowder

1
Eğer useEffectboş bir bağımlılık listesi vardır [], bu sadece ilk işlemek sırasında çalıştırılacaktır. Yani theArrayetkinin iç değeri her zaman olacaktır initialArray. Durumlarda setTheArray([...initialArray, newElement])anlamlı olmaz ve ne zaman theArraysabiti her zaman eşit olacaktır initialValue, daha sonra fonksiyonel güncelleştirme gerekmektedir.
Nisan 9'19

@Aprillion - Korkarım hala anlamıyorum, muhtemelen biraz yoğun. :-) Neden sadece ilk dizi değerine sahip bir etkiye ihtiyacınız var ? (Yani, sık olmayan bir kullanım durumu olabilir, ama ...) Ve yapsanız bile, bunun soruyla ne alakası var?
TJ Crowder

Hey @TJCrowder, ben verileriniz getirilirken yeni ile eski verileri birleştirmek için geri arama yolunu kullanmak değilim, ama nedense bunu kontrol edin edebilirsiniz düzgün iyi çalışmaz oluyor bu benim sorunu anlamak için?
Oliver D

46

Biraz daha genişletmek için işte bazı yaygın örnekler. Şununla başlayarak:

const [theArray, setTheArray] = useState(initialArray);
const [theObject, setTheObject] = useState(initialObject);

Dizinin sonundaki öğeyi itin

setTheArray(prevArray => [...prevArray, newValue])

Nesnenin sonundaki öğeyi it / güncelle

setTheObject(prevState => ({ ...prevState, currentOrNewKey: newValue}));

Nesne dizisinin sonundaki öğeyi it / güncelle

setTheArray(prevState => [...prevState, {currentOrNewKey: newValue}]);

Dizi nesnesinin sonundaki öğeyi itin

let specificArrayInObject = theObject.array.slice();
specificArrayInObject.push(newValue);
const newObj = { ...theObject, [event.target.name]: specificArrayInObject };
theObject(newObj);

İşte bazı çalışma örnekleri de. https://codesandbox.io/s/reacthooks-push-r991u


4
Tüm örnekler için teşekkür ederim. Sorun yaşadığım şey tam olarak dizi nesnesinin sonundaki Push öğenizdi . Çok farklı şeyler denedim ama bir araya getiremedim.
sdouble

5

Aynı React sınıfı bileşenlerde "normal" durumla yaptığınız gibi.

misal:

function App() {
  const [state, setState] = useState([]);

  return (
    <div>
      <p>You clicked {state.join(" and ")}</p>
      //destructuring
      <button onClick={() => setState([...state, "again"])}>Click me</button>
      //old way
      <button onClick={() => setState(state.concat("again"))}>Click me</button>
    </div>
  );
}

bu, onClick ile çalışacaktır, ancak setState (oldState => [... oldState, pushsomething]) bunu nasıl yapmanız gerektiğidir
Cyrus Zei

3
// Save search term state to React Hooks with spread operator and wrapper function

// Using .concat(), no wrapper function (not recommended)
setSearches(searches.concat(query))

// Using .concat(), wrapper function (recommended)
setSearches(searches => searches.concat(query))

// Spread operator, no wrapper function (not recommended)
setSearches([...searches, query])

// Spread operator, wrapper function (recommended)
setSearches(searches => [...searches, query])

https://medium.com/javascript-in-plain-english/how-to-add-to-an-array-in-react-state-3d08ddb2e1dc


2

setTheArray([...theArray, newElement]);en basit cevaptır, ancak Dizideki öğelerin değişmesine dikkat edin . Dizi öğelerinin derinlemesine klonlanmasını kullanın.


Bahsettiğiniz derin klonlama, objA olarak almak anlamına mı geliyor? UseState ve objA'yı objB ile birleştirmek? Bu bağlantıyla aynı mı? gist.githubusercontent.com/kahsing/…
Luiey

1

En çok önerilen yöntem, sarmalayıcı işlevi ve yayma işlecini birlikte kullanmaktır. Örneğin, böyle bir durumu başlattıysanız name,

const [names, setNames] = useState([])

Bu diziye şu şekilde basabilirsiniz,

setNames(names => [...names, newName])

Umarım yardımcı olur.


Lütfen yalnızca bağlantı içeren yanıtlar göndermeyin. Bağlantı gelecekte kopabilir. Bunun yerine, o makalenin bir yazısını oluşturun ve soruyu gerçekten cevapladığınızdan emin olun.
BlackCetha

Bu bağlantı soruyu cevaplayabilirken, cevabın temel kısımlarını buraya eklemek ve referans için bağlantıyı sağlamak daha iyidir. Bağlantılı sayfa değişirse yalnızca bağlantı yanıtları geçersiz hale gelebilir. - Yorumdan
ilke444

0

Bir nesneyi useState'teki bir nesne dizisine itmek için yukarıdaki yöntemleri denedim, ancak TypeScript kullanırken şu hatayı aldım :

'TxBacklog [] yazın | undefined ', yineleyici.ts (2488) döndüren' Symbol.iterator 'yöntemine sahip olmalıdır

Tsconfig.json için kurulum görünüşe göre doğruydu:

{
   "compilerOptions": {
   "target": "es6",
   "lib": [
      "dom",
      "dom.iterable",
      "esnext",
      "es6",
],

Bu geçici çözüm sorunu çözdü (örnek kodum):

Arayüz:

   interface TxBacklog {
      status: string,
      txHash: string,
   }

Durum değişkeni:

    const [txBacklog, setTxBacklog] = React.useState<TxBacklog[]>();

Yeni nesneyi diziye itin:

    // Define new object to be added
    const newTx = {
       txHash: '0x368eb7269eb88ba86..',
       status: 'pending'
    };
    // Push new object into array
    (txBacklog) 
       ? setTxBacklog(prevState => [ ...prevState!, newTx ])
       : setTxBacklog([newTx]);

0

belirli bir dizinden sonra itmek istiyorsanız, aşağıdaki işlemleri yapabilirsiniz:

   const handleAddAfterIndex = index => {
       setTheArray(oldItems => {
            const copyItems = [...oldItems];
            const finalItems = [];
            for (let i = 0; i < copyItems.length; i += 1) {
                if (i === index) {
                    finalItems.push(copyItems[i]);
                    finalItems.push(newItem);
                } else {
                    finalItems.push(copyItems[i]);
                }
            }
            return finalItems;
        });
    };
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.