首页  >  问答  >  正文

为什么每个 React 组件都需要使用 useDispatch?

是的,这个问题似乎与这个问题重复:

每个组件应该有一个 useDispatch 吗?

但它并不重复。我提供不同的方法:

假设我有 3 个子组件,它们都使用 Redux Toolkit 的调度函数。

通常的方式是这样的:

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>
  );
};

但是如果我这样做呢?请参阅:

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>
  );
};

经我测试,它也运行良好。请告诉我,为什么我应该按照通常的方式做?现在新代码(基于 glo 的代码)更大,但那是因为我们只有 3 个子组件。当我们有 30 多个子组件时,基于 glo 的代码将会小得多,也更容易理解。

这里是差异:

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

这是 CodeSandbox 链接:

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

P粉291886842P粉291886842226 天前441

全部回复(1)我来回复

  • P粉845862826

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

    例如,该调度函数将在您的测试中发生变化。

    如果没有测试,在某些环境中这样做本身并不是“错误”,但也不是一个大胜利。
    如果你的应用程序中有一行 const dispatch = useAppDispatch(); ,那么很有可能,当 js 包被 gzip 传输时(现在这很正常),它会 gzip 到 3 或 4无论如何字节。

    如果您确实想删除此处的代码,请删除 useCallback ,因为将回调直接传递到 html 时完全没有必要。

    回复
    0
  • 取消回复