简体   繁体   English

带有回调的自定义 React Hook 正在关闭

[英]Custom React Hook with callback is making closure

What I am trying to achieve is a custom hook that calls a callback on particular keypress.我想要实现的是一个自定义钩子,它在特定的按键上调用回调。 The thing is that the callback is dependant on component prop.问题是回调依赖于组件道具。 Unfortunately callback is passed to the hook only once and it makes closure on prop value.不幸的是,回调只传递给钩子一次,并且它关闭了 prop 值。

Hook Code:挂钩代码:

export default function useKeyPress(targetKey, callback) {
  const keyPressedHandler = ({ key }) => {
    if (key === targetKey && callback && typeof callback === 'function') {
      callback();
    }
  };

  useEffect(() => {
    window.addEventListener('keyup', keyPressedHandler);
    return () => {
      window.removeEventListener('keyup', keyPressedHandler);
    };
  }, []);
}

Component that uses a hook:使用钩子的组件:

const Component = ({ isActive }) => {
  // isActive is changing here
  useKeyPress('ArrowRight', () => {
    if (isActive) // isActive always has the initial value 
      // do something if isActive is true
  });
}

How can I rewrite my hook or how should I handle this kind of situation?我该如何重写我的钩子或者我应该如何处理这种情况?

I have reproduced the issue on Codepen https://codepen.io/tedseds/pen/oNXzvoK我已经在 Codepen https://codepen.io/tedseds/pen/oNXzvoK上重现了这个问题

When you press arrow right it always logs isActive as false even when the prop is changed.当您按向右箭头时,即使道具更改,它也始终将isActive记录为 false。

Solution https://codepen.io/tedseds/pen/ZEGpzPm解决方案https://codepen.io/tedseds/pen/ZEGpzPm

You need to pass prop callback as a dependancy to the useEffect .您需要将 prop callback作为依赖项传递给useEffect It will reattach the event listener with the latest callback.它将使用最新的回调重新附加事件侦听器。

Code:代码:

function useKeyPress(targetKey, callback) {
  const keyPressedHandler = ({ key }) => {
    if (key === targetKey && callback && typeof callback === "function") {
      callback();
    }
  };

  useEffect(() => {
    window.addEventListener("keyup", keyPressedHandler);
    return () => {
      window.removeEventListener("keyup", keyPressedHandler);
    };
  }, [callback]);
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM