Catatan tentang bagaimana status pembaruan React





Selamat siang teman!



Hook useState () mengelola status dalam komponen fungsional React. Dalam kacang kelas, status disimpan di this.state, dan metode this.setState () dipanggil untuk memperbarui.



Biasanya, tidak ada yang sulit dalam bekerja dengan negara. Namun, ada satu nuansa penting yang terkait dengan pembaruannya.



Bagaimana status diperbarui: segera (sinkron) atau ditangguhkan (asinkron)? Baca terus untuk mengetahui jawabannya.



1. Memperbarui status dengan useState ()



Katakanlah kita memiliki komponen fungsional seperti itu:



import { useState } from 'react'

function DoubleIncreaser() {
  const [count, setCount] = useState(0)

  const doubleIncreaseHandler = () => {
    setCount(count + 1)
    setCount(count + 1)
  }

  return (
    <>
      <button onClick={doubleIncreaseHandler}>
        Double Increase
      </button>
      <div>Count: {count}</div>
    </>
  )
}

      
      





const [count, setCount] = useState (0) mendefinisikan status awal komponen. count adalah variabel yang berisi keadaan saat ini, dan setCount adalah fungsi untuk memperbarui keadaan ini.



Komponen tersebut berisi tombol Peningkatan Ganda. Saat tombol ini diklik, penangan doubleIncreaseHandler dipanggil, yang melakukan dua pembaruan berturut-turut untuk menghitung: setCount (count + 1) dan kemudian setCount (count + 1) lagi.



Bagaimana status komponen setelah mengklik tombol, 1 atau 2?



Buka demo ini dan klik tombolnya. Nilai hitungan akan meningkat 1 setelah setiap klik.



Ketika setCount (count + 1) memperbarui status, nilai hitungan tidak langsung berubah. Sebagai gantinya, React menjadwalkan status untuk diperbarui dan saat berikutnya dirender, dalam const [count, setCount] = useState (0), hook memberikan nilai baru untuk dihitung.



Misalnya: jika nilai dari variabel count adalah 0, maka panggil setCount (count + 1); setCount (count + 1) mengevaluasi ke setCount (0 + 1); setCount (0 + 1) - yang menghasilkan 1 sebagai nilai status pada render berikutnya.



Oleh karena itu, memperbarui status menggunakan setValue (newValue) di [value, setValue] = useState () dilakukan secara asinkron.



Namun, fungsi pembaruan status dapat menggunakan callback sebagai argumen untuk menghitung status baru berdasarkan status saat ini. Dalam kasus kami, kami dapat menggunakan setCount (actualCount => actualCount + 1):



import { useState } from 'react'

function DoubleIncreaser() {
  const [count, setCount] = useState(0)

  const doubleIncreaseHandler = () => {
    setCount(actualCount => actualCount + 1)
    setCount(actualCount => actualCount + 1)
  }

  return (
    <>
      <button onClick={doubleIncreaseHandler}>
        Double Increase
      </button>
      <div>Count: {count}</div>
    </>
  )
}

      
      





Saat memperbarui status menggunakan fungsi seperti itu, argumen aktualCount akan berisi nilai status aktual.



Buka demo ini dan klik tombolnya. Hitungan akan meningkat menjadi 2 seperti yang diharapkan.



Tentu saja, kami selalu dapat membuat variabel perantara:



import { useState } from 'react'

function DoubleIncreaser() {
  const [count, setCount] = useState(0)

  const doubleIncrease = () => {
    let actualCount = count
    actualCount = actualCount + 1
    actualCount = actualCount + 1
    setCount(actualCount)
  }

  return (
    <>
      <button onClick={this.doubleIncrease}>
        Double Increase
      </button>
      <div>Count: {count}</div>
    </>
  )
}

      
      





biarkan actualCount = count adalah variabel perantara yang dapat diperbarui sesuka Anda. Variabel ini digunakan untuk memperbarui keadaan menggunakan setCount (actualCount).



2. Status tidak dapat diubah (tidak berubah) dan hanya-baca



Jika Anda lupa bahwa status diperbarui pada render berikutnya, Anda dapat mencoba membaca nilai segera setelah nilainya berubah. Sayangnya, Anda tidak akan mendapatkan apa pun:



function FetchUsers() {
  const [users, setUsers] = useState([])

  useEffect(() => {
    const startFetching = async () => {
      const response = await fetch('/users')
      const fetchedUsers = await response.json()

      setUsers(fetchedUsers)
      console.log(users)        // => []
      console.log(fetchedUsers) // => ['John', 'Jane', 'Alice', 'Bob']
    }
    startFetching()
  }, [])

  return (
    <ul>
      {users.map(user => <li>{user}</li>)}
    </ul>
  )
}

      
      





Komponen FetchUsers mengirimkan permintaan mount - startFetching ().



Saat data diterima, setUsers (fetchedUsers) memperbarui status. Namun, perubahan tidak terjadi dalam semalam.



Variabel pengguna tidak dapat diubah dan hanya-baca. Hanya hook useState () yang bisa memberikan nilai baru padanya. Anda tidak dapat melakukan ini secara langsung:



  function FetchUsers() {
    const [users, setUsers] = useState([])

    useEffect(() => {
      const startFetching = async () => {
        const response = await fetch('/users')
        const fetchedUsers = await response.json()

        users = fetchedUsers       // ! users    
        users.push(...fetchedUsers) // ! users 
        setUsers(fetchedUsers)     // !
      }
      startFetching()
    }, [])

    return (
      <ul>
        {users.map(user => <li>{user}</li>)}
      </ul>
    )
  }

      
      





3. Memperbarui status dalam komponen kelas



Pembaruan status asinkron umum untuk komponen kelas.



Mari pertimbangkan sebuah contoh:



import { Component } from 'react';

class DoubleIncreaser extends Component {
  state = {
    count: 0
  };

  render() {
    return (
      <>
        <button onClick={this.doubleIncrease}>
          Double Increase
        </button>
        <div>Count: {this.state.count}</div>
      </>
    );
  }

  doubleIncrease = () => {
    // !
    this.setState(({ count }) => ({
      count: count + 1
    }));
    this.setState(({ count }) => ({
      count: count + 1
    }));

    //  !
    // this.setState({ count: this.state.count + 1 });
    // this.setState({ count: this.state.count + 1 });
  }
}

      
      





Perhatikan penangan doubleIncrease (): ia menggunakan fungsi callback untuk memperbarui status.



Buka demo ini dan klik tombolnya. Nilai this.state akan meningkat menjadi 2.



Dalam komponen kelas, this.state juga tidak diupdate secara instan. Ketika this.setState (newState) dipanggil, React menunda memperbarui this.state hingga render berikutnya.



Jadi this.setState (newState) memperbarui this.state secara asynchronous.



4. Kesimpulan



Hook useState () dan this.setState () (di dalam komponen kelas) memperbarui nilai variabel dan status komponen secara asynchronous.



Ingat aturan sederhana: memanggil setter setState (newValue) dari hook useState () (atau this.setState ()) tidak langsung memperbarui status, tetapi pada rendering komponen berikutnya.



Pernahkah Anda memperhatikan bahwa React sekarang hanya perlu diimpor sekali (di index.js)? Ini tidak lagi diperlukan di komponen.



Terima kasih atas perhatiannya dan semoga harimu menyenangkan.



All Articles