将Memasukkan tatasusunan sebagai kebergantungan dalam useEffect
P粉748218846
P粉748218846 2023-10-17 18:50:23
0
2
556

Terdapat beberapa data yang masuk daripada tinjauan panjang setiap 5 saat dan saya mahu komponen saya menghantar operasi setiap kali item tatasusunan (atau panjang tatasusunan itu sendiri) berubah. Bagaimanakah cara saya menghalang useEffect daripada masuk ke gelung tak terhingga apabila menghantar tatasusunan sebagai kebergantungan, tetapi masih dapat menjadualkan beberapa operasi jika ada perubahan nilai?

useEffect(() => {
  console.log(outcomes)
}, [outcomes])

di mana outcomes 是一个 ID 数组,例如 [123, 234, 3212]。数组中的项目可能会被替换或删除,因此数组的总长度可能(但不一定)保持不变,因此传递 outcomes.length sebagai tanggungan tidak berlaku.

outcomes Pemilih tersuai daripada pemilihan semula:

const getOutcomes = createSelector(
  someData,
  data => data.map(({ outcomeId }) => outcomeId)
)


P粉748218846
P粉748218846

membalas semua(2)
P粉464208937

Menggunakan JSON.stringify() atau mana-mana kaedah perbandingan mendalam mungkin kurang cekap, jika anda mengetahui bentuk objek lebih awal, anda boleh menulis cangkuk kesan anda sendiri untuk mencetuskan panggilan balik ke fungsi kesamaan tersuai anda berdasarkan hasilnya.

useEffect 的工作原理是检查依赖项数组中的每个值是否与前一渲染中的值相同,如果其中一个不是,则执行回调。因此,我们只需要使用 useRef 保留我们感兴趣的数据实例,并且仅在自定义相等性检查返回 false Tetapkan kejadian baharu untuk mencetuskan kesan.

function arrayEqual(a1: any[], a2: any[]) {
  if (a1.length !== a2.length) return false;
  for (let i = 0; i  void);

function useNumberArrayEffect(cb: () => MaybeCleanUpFn, deps: number[]) {
  const ref = useRef(deps);

  if (!arrayEqual(deps, ref.current)) {
    ref.current = deps;
  }

  useEffect(cb, [ref.current]);
}

Penggunaan

function Child({ arr }: { arr: number[] }) {
  useNumberArrayEffect(() => {
    console.log("run effect", JSON.stringify(arr));
  }, arr);

  return 
{JSON.stringify(arr)}
; }

Melangkah lebih jauh, kami juga boleh menggunakan semula cangkuk ini dengan mencipta cangkuk kesan yang menerima fungsi kesamaan tersuai.

type MaybeCleanUpFn = void | (() => void);
type EqualityFn = (a: DependencyList, b: DependencyList) => boolean;

function useCustomEffect(
  cb: () => MaybeCleanUpFn,
  deps: DependencyList,
  equal?: EqualityFn
) {
  const ref = useRef(deps);

  if (!equal || !equal(deps, ref.current)) {
    ref.current = deps;
  }

  useEffect(cb, [ref.current]);
}

Penggunaan

useCustomEffect(
  () => {
    console.log("run custom effect", JSON.stringify(arr));
  },
  [arr],
  (a, b) => arrayEqual(a[0], b[0])
);

Demonstrasi secara langsung

P粉662802882

Anda boleh lulus JSON.stringify(outcomes) sebagai senarai tanggungan:

Ketahui lebih lanjut di sini

useEffect(() => {
  console.log(outcomes)
}, [JSON.stringify(outcomes)])
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan