【发布时间】:2020-11-15 19:49:47
【问题描述】:
当 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 事件。问题是重新渲染发生在第二个钩子开始之前。
我找到了一些解决方案,但两者都不喜欢:
- 在第一个 hook mousedown 属性中使用
setTimeout(() => dispatch(increment()), 0)之类的东西。但在重用方面似乎并不明显。 - 将两个钩子重写为一个并使用一个“大”mousedown 处理程序进行操作。但在这种情况下,组合钩子可能难以维护。
所以我需要一个允许保持结构不变的解决方案(我的意思是两个单独的钩子),但第二个钩子也可以工作。有人能帮忙怎么弄吗?
【问题讨论】:
-
为什么不定义两个函数来处理你的逻辑,然后在一个钩子中触发它们?
-
是的,我想过。主要思想是第一个和第二个钩子在逻辑上是不同的。我的意思是,例如,第一个钩子应该负责鼠标点击,第二个钩子应该负责拖动。所以......在某个地方单独使用它们会很棒
标签: reactjs redux react-hooks redux-thunk