首页 > 解决方案 > React + Redux + Thunk:同一事件上的多个钩子

问题描述

当 state 和 redux store 应该一起工作时,我遇到了 hook 重用的问题。我已经简化了代码来显示问题。

有一个组件我想使用多个钩子(为简单起见,我在这里重用useMouseDown钩子):

export function Counter() {
  const count = useSelector(selectCount);
  const dispatch = useDispatch();
  const plusSighRef = useRef<HTMLButtonElement>(null);

  useMouseDown({
    ref: plusSighRef,
    onMouseDown: () => {
      console.log('in first hook');
      dispatch(increment());
    }
  });

  useMouseDown({
    ref: plusSighRef,
    onMouseDown: () => { console.log('in second hook'); }
  });

  return <button ref={plusSighRef}>+</button>;
}

每个钩子都有内部状态,并且在鼠标按下事件上有自己的回调:

const useMouseDown = ({ ref, onMouseDown }) => {
  const [isClicked, setIsClicked] = useState(false);
  useEffect(() => {
    const element = ref.current;

    const down = (e: MouseEvent) => {
      setIsClicked(true);
      onMouseDown(e);
    }
    element.addEventListener('mousedown', down);

    return (): void => {
      element.removeEventListener('mousedown', down);
    };
  }, [onMouseDown, ref]);
}

因此,永远不会触发第二个挂钩中的 mousedown 事件。问题是重新渲染发生在第二个钩子开始之前。

我找到了一些解决方案,但两者都不喜欢:

  1. setTimeout(() => dispatch(increment()), 0)在第一个 hook mousedown 道具中使用类似的东西。但在重用方面似乎并不明显。
  2. 将两个钩子重写为一个并使用一个“大”mousedown 处理程序进行操作。但在这种情况下,组合挂钩可能难以维护。

所以我需要一个允许保持结构不变的解决方案(我的意思是两个单独的钩子),但第二个钩子也在工作。有人可以帮助如何获得它吗?

标签: reactjsreduxreact-hooksredux-thunk

解决方案


你不能把你的逻辑放在两个不同的函数中,然后在钩子的onMouseDown函数中顺序执行吗?

const executeFirstFlow = () => {
  console.log('in first function');
  dispatch(increment());
};

const executeSecondFlow = () => {
  console.log('in second function');
};

useMouseDown({
    ref: plusSighRef,
    onMouseDown: () => {
        executeFirstFlow();
        executeSecondFlow();
    }
});

推荐阅读