Bolehkah saya menggunakan React.useCallback di dalam React.useCallback yang lain?
P粉153503989
P粉153503989 2023-09-01 14:55:58
0
1
527
<p>有一个渲染用户卡片的组件</p> <p> <pre class="brush:js;toolbar:false;">import React daripada "react"; const Pengguna = React.memo(fungsi({id, nama, isSelected, ...other}) { kembali ( <div {...other}> {name} - {isSelected && "Dipilih"} </div> ); }); eksport Pengguna lalai;</pre> </p> <p>以及渲染用户卡的父组件</p> <p> <pre class="brush:js;toolbar:false;">import React daripada "react"; fungsi Aplikasi() { const [pengguna, setUsers] = React.useState([ {id: 1, nama: "John Doe #1"}, {id: 2, nama: "John Doe #2"}, {id: 3, nama: "John Doe #3"} ]); const [selectedUserId, setSelectedUserId] = React.useState(null); kembalikan pengguna.peta((pengguna) => { const isSelected = selectedUserId === user.id; kembali ( <Pengguna {...pengguna} key={user.id} isSelected={isSelected} onClick={() => setSelectedUserId(user.id)} /> ); }); } eksport lalai Aplikasi;</pre> </p> <p>任务是“选择用户后避免重新渲染其他用户卡”</p> <p>我尝试使用 <kod>React.useCallback</code> 钩子,这是我的第一个实现</p> <p> <pre class="brush:js;toolbar:false;">import React daripada "react"; const Pengguna = React.memo(fungsi({id, nama, isSelected, ...other}) { kembali ( <div {...other}> {name} - {isSelected && "Dipilih"} </div> ); }); fungsi Aplikasi() { const [pengguna, setUsers] = React.useState([ {id: 1, nama: "John Doe #1"}, {id: 2, nama: "John Doe #2"}, {id: 3, nama: "John Doe #3"} ]); const [selectedUserId, setSelectedUserId] = React.useState(null); const handleSelectUser = React.useCallback((userId) => () => { setSelectedUserId(userId); }, []); kembalikan pengguna.peta((pengguna) => { const isSelected = selectedUserId === user.id; kembali ( <Pengguna {...pengguna} key={user.id} isSelected={isSelected} onClick={handleSelectUser(user.id)} /> ); }); } eksport lalai Aplikasi;</pre> </p> <p>Dalam kes ini, <code>React.useCallback</code> mengembalikan fungsi tanpa nama</p> <p><strong>Hasil: Semua kad pengguna masih dipaparkan semula selepas setiap klik</strong></p> <p>Saya memutuskan untuk membungkus fungsi tanpa nama ini dalam <code>React.useCallback</code></p> <p> <pre class="brush:js;toolbar:false;">import React daripada "react"; const Pengguna = React.memo(fungsi({id, nama, isSelected, ...other}) { kembali ( <div {...other}> {name} - {isSelected && "Selected"} </div> ); }); fungsi Aplikasi() { const [pengguna, setUsers] = React.useState([ {id: 1, nama: "John Doe #1"}, {id: 2, nama: "John Doe #2"}, {id: 3, nama: "John Doe #3"} ]); const [selectedUserId, setSelectedUserId] = React.useState(null); const handleSelectUser = React.useCallback((userId) => { kembalikan React.useCallback(() => { setSelectedUserId(userId); }, []); }, []); kembalikan pengguna.peta((pengguna) => { const isSelected = selectedUserId === user.id; kembali ( <Pengguna {...pengguna} key={user.id} isSelected={isSelected} onClick={handleSelectUser(user.id)} /> ); }); } eksport lalai Aplikasi;</pre> </p> <p>Masalah sudah selesai, tetapi masih ada satu soalan, adakah saya melakukannya dengan betul? Pasukan React berkata: <em>Jangan panggil Hooks dalam gelung, bersyarat atau fungsi bersarang</em> </p> <p>Perhatikan jangan sentuh <kod>pengguna</kod>komponen</p>
P粉153503989
P粉153503989

membalas semua(1)
P粉810050669

Terangkan mengapa cangkuk tidak boleh dipanggil dari dalam cangkuk (dan harapkan ia berfungsi secara konsisten dan boleh dipercayai)

Mengapa anda tidak boleh memanggil cangkuk di dalam cangkuk - pergi ke sini untuk menyelam yang sangat mendalam dengan lebih banyak konteks daripada yang perlu saya berikan dalam jawapan ini https://overreacted.io/why-do-hooks-rely-on -call-order/

Penyelesaian anda berfungsi kerana walaupun "melanggar peraturan" susunan panggilan ke cangkuk sentiasa sama...sehingga pengguna ditambah atau dialih keluar dari keadaan.

Anda pasti boleh menggunakan penyelesaian yang anda tulis. Tetapi bagaimana jika anda perlu menukar bilangan pengguna?


Tidak, anda tidak boleh menggunakan cangkuk di dalam cangkuk. Ia mungkin "berfungsi", tetapi React memberitahu anda bahawa ia tidak berfungsi dengan pasti dan anda melakukannya dengan salah. Cangkuk mesti dipanggil di peringkat atas komponen peringkat atas cangkuk tersuai.

Anda berada di arah yang betul, tetapi penyelesaian kepada masalah adalah

  1. Gunakan parameter yang disediakan untuk fungsi panggil balik sebagai sumber elemen yang diklik DAN
  2. Jika anda tidak boleh mengubah suai komponen Pengguna, anda perlu menyediakan beberapa data pada elemen div untuk memberitahu anda elemen pengguna yang telah diklik.

Ia kelihatan seperti ini:

function Application() {
  const [users, setUsers] = React.useState([
    { id: 1, name: 'John Doe #1' },
    { id: 2, name: 'John Doe #2' },
    { id: 3, name: 'John Doe #3' },
  ]);
  const [selectedUserId, setSelectedUserId] = React.useState(null);

  // this callback is referentially stable - it doesn't change between renders because it has no dependencies
  const handleSelectUser = React.useCallback((e) => {
    setSelectedUserId(+e.target.getAttribute('data-userid'));
  }, []);

  return users.map((user) => {
    const isSelected = selectedUserId === user.id;

    return (
      <User
        {...user}
        data-userid={user.id} <- this line
        key={user.id}
        isSelected={isSelected}
        onClick={handleSelectUser}
      />
    );
  });
}
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!