Rumah  >  Soal Jawab  >  teks badan

Mengapa anda perlu menggunakan React useState dalam bentuk kemas kini berfungsi?

Saya sedang membaca dokumentasi React Hook mengenai kemas kini ciri dan melihat petikan berikut:

Butang "+" dan "-" menggunakan bentuk berfungsi kerana kemas kini Nilai adalah berdasarkan nilai sebelumnya

Tetapi saya tidak nampak apakah tujuan memerlukan kemas kini ciri dan apakah perbezaan antara mereka dan secara langsung menggunakan keadaan lama untuk mengira keadaan baharu.

Mengapa React useState Hook fungsi pengemas kini memerlukan borang kemas kini berfungsi? Adakah terdapat sebarang contoh di mana kita dapat melihat perbezaannya dengan jelas (dan dengan itu menggunakan kemas kini langsung akan menyebabkan ralat)?

Sebagai contoh, jika saya menukar contoh ini daripada dokumentasi

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
    </>
  );
}

Kemas kini teruscount:

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(count - 1)}>-</button>
    </>
  );
}

Saya tidak nampak apa-apa perbezaan dalam tingkah laku dan tidak dapat membayangkan situasi di mana kiraan tidak akan dikemas kini (atau tidak dikemas kini). Kerana setiap kali kiraan berubah, penutupan baharu onClick dipanggil, menangkap onClick 的新闭包,捕获最新的 count terkini.

P粉155551728P粉155551728334 hari yang lalu640

membalas semua(2)saya akan balas

  • P粉818125805

    P粉8181258052023-10-23 10:02:44

    Saya terjumpa keperluan ini baru-baru ini. Sebagai contoh, katakan anda mempunyai komponen yang mengisi tatasusunan dengan bilangan elemen tertentu dan boleh menambah tatasusunan itu berdasarkan beberapa tindakan pengguna (seperti dalam kes saya, saya memuatkan suapan 10 item pada satu masa kerana pengguna menyimpan Tatal ke bawah dan kod kelihatan seperti ini sedikit:

    function Stream() {
      const [feedItems, setFeedItems] = useState([]);
      const { fetching, error, data, run } = useQuery(SOME_QUERY, vars);
    
      useEffect(() => {
        if (data) {
          setFeedItems([...feedItems, ...data.items]);
        }
      }, [data]);     // <---- this breaks the rules of hooks, missing feedItems
    
    ...
    <button onClick={()=>run()}>get more</button>
    ...

    Jelas sekali anda tidak boleh hanya menambah feedItems pada senarai dependencies dalam useEffect hook kerana anda memanggil setFeedItems di dalamnya, jadi anda akan terperangkap dalam satu gelung.

    Kemas kini ciri untuk menyelamatkan:

    useEffect(() => {
        if (data) {
          setFeedItems(prevItems => [...prevItems, ...data.items]);
        }
      }, [data]);     //  <--- all good now

    balas
    0
  • P粉457445858

    P粉4574458582023-10-23 09:44:55

    Kemas kini keadaan dalam React adalah tidak segerak. Jadi apabila anda mengemas kini seterusnya, mungkin terdapat nilai lama dalam count. Sebagai contoh, bandingkan hasil kedua-dua contoh kod ini:

    function Counter({initialCount}) {
      const [count, setCount] = useState(initialCount);
      return (
        <>
          Count: {count}
          <button onClick={() => setCount(initialCount)}>Reset</button>
          <button onClick={() => {
            setCount(prevCount => prevCount + 1); 
            setCount(prevCount => prevCount + 1)}
          }>+</button>
        </>
      );
    }

    dan

    function Counter({initialCount}) {
      const [count, setCount] = useState(initialCount);
      return (
        <>
          Count: {count}
          <button onClick={() => setCount(initialCount)}>Reset</button>
          <button onClick={() => {
            setCount(count + 1); 
            setCount(count + 1)}
          }>+</button>
        </>
      );
    }

    balas
    0
  • Batalbalas