Rumah  >  Soal Jawab  >  teks badan

Mengapa setiap komponen React perlu menggunakan useDispatch?

Ya, soalan ini nampaknya adalah pendua soalan ini:

Adakah setiap komponen mempunyai useDispatch?

Tetapi ia tidak berulang. Saya menawarkan kaedah yang berbeza:

Andaikan saya mempunyai 3 komponen anak dan semuanya menggunakan fungsi penghantaran Redux Toolkit.

Cara biasa adalah begini:

const ChildA = () => {
  const dispatch = useAppDispatch();

  const incr = useCallback(() => {
    dispatch(increment());
  }, [dispatch]);

  return <button onClick={incr}>ChildA</button>;
};

const ChildB = () => {
  const dispatch = useAppDispatch();

  const incr = useCallback(() => {
    dispatch(increment());
  }, [dispatch]);

  return <button onClick={incr}>ChildB</button>;
};

const ChildC = () => {
  const dispatch = useAppDispatch();

  const incr = useCallback(() => {
    dispatch(increment());
  }, [dispatch]);

  return <button onClick={incr}>ChildC</button>;
};

export const MyApp = () => {
  const dispatch = useAppDispatch();

  const count = useAppSelector((state) => state.counter.value);

  const incr = useCallback(() => {
    dispatch(increment());
  }, [dispatch]);

  return (
    <div>
      <button onClick={incr}>MyApp</button>

      <ChildA />
      <ChildB />
      <ChildC />

      <div>{count}</div>
    </div>
  );
};

Tetapi bagaimana jika saya melakukan ini? Lihat:

export const glo: {
  dispatch: ReturnType<typeof useAppDispatch>;
} = {
  // @ts-ignore
  dispatch: null
};

const ChildA = () => {
  const incr = useCallback(() => {
    glo.dispatch(increment());
  }, []);

  return <button onClick={incr}>ChildA</button>;
};

const ChildB = () => {
  const incr = useCallback(() => {
    glo.dispatch(increment());
  }, []);

  return <button onClick={incr}>ChildB</button>;
};

const ChildC = () => {
  const incr = useCallback(() => {
    glo.dispatch(increment());
  }, []);

  return <button onClick={incr}>ChildC</button>;
};

export const MyApp = () => {
  const dispatch = useAppDispatch();
  glo.dispatch = dispatch;
  if (!glo.dispatch) {
    throw new Error("dispatch is falsy");
  }

  const count = useAppSelector((state) => state.counter.value);

  const incr = useCallback(() => {
    glo.dispatch(increment());
  }, []);

  return (
    <div>
      <button onClick={incr}>MyApp</button>

      <ChildA />
      <ChildB />
      <ChildC />

      <div>{count}</div>
    </div>
  );
};

Selepas ujian saya, ia juga berfungsi dengan baik. Tolong beritahu saya mengapa saya perlu melakukannya dengan cara biasa? Kini kod baharu (kod berasaskan glo) lebih besar, tetapi itu kerana kita hanya mempunyai 3 subkomponen. Apabila kita mempunyai 30+ subkomponen, kod berasaskan glo akan menjadi lebih kecil dan lebih mudah difahami.

Berikut adalah perbezaannya:

https://i.ibb.co/tKWv2Qc/image.png

Ini ialah pautan CodeSandbox:

https://codesandbox.io/s/clever-monad-c99q3k?file=/src/features/index.tsx

P粉291886842P粉291886842175 hari yang lalu395

membalas semua(1)saya akan balas

  • P粉845862826

    P粉8458628262024-03-29 12:59:55

    Sebagai contoh, fungsi penghantaran ini akan berubah dalam ujian anda.

    Tanpa ujian, melakukan ini dalam sesetengah persekitaran bukanlah "pepijat" semata-mata, tetapi ia juga bukan satu kemenangan besar.
    Jika anda mempunyai baris const dispatch = useAppDispatch(); dalam aplikasi anda, kemungkinan besar, apabila pakej js digzip (yang biasa pada masa kini), ia akan gzip kepada 3 atau 4 bait pula.

    Jika anda benar-benar ingin mengalih keluar kod di sini, keluarkan useCallback kerana ia tidak diperlukan sama sekali apabila menghantar panggilan balik terus ke html.

    balas
    0
  • Batalbalas