当 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 事件。问题是重新渲染发生在第二个钩子开始之前。
我找到了一些解决方案,但两者都不喜欢:
setTimeout(() => dispatch(increment()), 0)
在第一个 hook mousedown 道具中使用类似的东西。但在重用方面似乎并不明显。- 将两个钩子重写为一个并使用一个“大”mousedown 处理程序进行操作。但在这种情况下,组合挂钩可能难以维护。
所以我需要一个允许保持结构不变的解决方案(我的意思是两个单独的钩子),但第二个钩子也在工作。有人可以帮助如何获得它吗?