React + useState () + PreviousState

Sep 11 2020

Saya cukup baru untuk bereaksi dan memiliki masalah dalam memahami useState Kait - atau lebih khusus aspek dari previousState .

Hook useState normal, dan mungkin contoh paling umum, terlihat seperti ini:

import React, { useState} from 'react';

export default function CounterHooks({ initialCount }){
  const [count, setCount] = useState(initialCount);

  return (
    <div>
      <button onClick={() => setCount(count -1)}>-</button>
      <span>{count}</span>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

Yang saya pahami sejauh ini, adalah sebagai berikut:

  • Saya memanggil fungsi useState () / Hook? dan berikan argumen dari State awal (initialCount)
  • Saya mendapatkan kembali array yang segera saya hancurkan menjadi variabel count dan setCount (yang berfungsi)
  • Dengan setCount () saya bisa mengupdate state dan oleh karena itu variabel count

Sejauh ini bagus, saya pikir ...;)

Terkadang saya melihat contoh penghitung yang sama dengan prevState (prevCount) yang tidak saya mengerti:

<button onClick={() => setCount(prevCount => prevCount -1)}>-</button>

Apa yang terjadi di sini? Bagian ini saya tidak mengerti. Pikiran saya sejauh ini:

  • Dalam hal ini, saya mengakses nilai hitungan sebelumnya.
  • setCount sekarang mengharapkan sebuah fungsi
  • setCount sekarang dijalankan secara asynchron
  • Dari mana asalnya fungsi ini?
  • Dari mana prevCount berasal?
  • Ketika saya menjalankan ini, apa yang dimasukkan ke prevCount?

Apakah Anda memahami kebingungan saya? Saya tidak yakin bagaimana saya harus membingkai ini secara berbeda ...

Terima kasih banyak atas bantuan Anda.

Jawaban

6 devserkan Sep 11 2020 at 19:15

Pertama-tama, Anda bisa melihat penjelasan resminya di sini .

Dalam hal ini, saya mengakses nilai hitungan sebelumnya.

Anda tidak entah bagaimana mengakses nilai hitungan sebelumnya. Jika Anda menggunakan pembaruan fungsional dan memberikan fungsi panggilan balik ke penyetel, ini mengembalikan status sebelumnya kepada Anda dan Anda menggunakan nilai ini dalam fungsi panggilan balik Anda.

setCount sekarang mengharapkan sebuah fungsi

Karena Anda menyediakan suatu fungsi, itu dapat menggunakannya.

setCount sekarang dijalankan secara asynchron

Sebenarnya tidak. Ini bukan fungsi asinkron. Ini hanya memberikan keadaan sebelumnya dan Anda menggunakannya. Penyetel status tidak asinkron, pembaruan status adalah.

Dari mana asalnya fungsi ini?

Dari mana prevCount berasal?

Sudah dijawab.

Ketika saya menjalankan ini, apa yang dimasukkan ke prevCount?

Anda memberikan apa yang Anda inginkan untuk mengatur keadaan baru di sana. Dalam contoh Anda, Anda ingin menambah count1, jadi Anda menyediakan+ 1

Berikut adalah penjelasan yang naif untuk logika ini. Hanya yang naif. Saya menambahkan ini untuk memberi contoh logika panggilan balik, ini tidak terkait dengan ReactsetState.

let state = 5;

function setState(val) {
  if (typeof val === "function") {
    return val(state);
  }

  return val;
}

const stateWithFunctionalUpdate = setState(prev => prev + 1);
const stateWithNormalUpdate = setState(9);
console.log(stateWithFunctionalUpdate);
console.log(stateWithNormalUpdate);

Mungkin contoh ini akan cocok untuk meniru logika pengaturan status React. Sekali lagi, hanya pendekatan yang naif.

let state = 5;

function setState(val) {
  if (typeof val === "function") {
    state = val(state);
  } else {
    state = val;
  }

}

setState(9);
setState(prev => prev + 1);

console.log("state", state);

Penampilan Mari di implementasi nyata dari useState(tanpa typings):

export function useState(initialState) {
  return useReducer(
    basicStateReducer,
    // useReducer has a special case to support lazy useState initializers
    initialState
  );
}

Nah, itu hanya digunakan di useReducerbalik tirai. Ini menetapkan status awal dan menggunakan basicStateReducer yaitu:

function basicStateReducer(state, action) {
  return typeof action === "function" ? action(state) : action;
}

Seperti pendekatan naif kami, ini mencari jenis actiondan berperilaku sesuai dengan itu. Akhirnya, inilah yang useReducer mengembalikan :

return [workInProgressHook.memoizedState, dispatch];

Jadi, pada akhirnya, jika kita menyediakan fungsi untuk useState, itu mengambilnya dan kemudian menjalankannya di status kita dan mengembalikan nilainya kembali.

1 VietDinh Sep 11 2020 at 19:10

Inilah pendapat saya bagaimana saya mengerti:

Dalam hal ini, saya mengakses nilai hitungan sebelumnya. -> setCount akan memeriksa param, jika param adalah callback, ia akan memanggil panggilan itu kembali dan meneruskan status sebelumnya untuk param. Hasil panggilan kembali akan menjadi status berikutnya.

setCount sekarang mengharapkan fungsi -> ya, fungsi menangani logika Anda dan mengembalikan status berikutnya.

setCount sekarang dijalankan asynchron -> fungsi ini sinkron tetapi setelah itu mengembalikan hasil. Pengait untuk setCount akan mengirimkan acara untuk memperbarui status berikutnya

Dari mana asalnya fungsi ini? -> Anda dapat melakukan apa saja dalam fungsi selama param akan menjadi keadaan saat ini dan mengembalikan keadaan berikutnya.

Dari mana prevCount berasal? -> akan diteruskan ketika memanggil setCount (itu didapat dari keadaan saat ini).

Ketika saya menjalankan ini, apa yang dimasukkan ke prevCount? -> keadaan setCount saat ini.

=> Contoh bagaimana mengirimkan nilai atau panggilan kembali ke setCount di sini: hook useState, fungsi setState. Mengakses nilai status sebelumnya