useCallback不继承父项

时间:2020-11-11 10:14:01

标签: javascript reactjs

我正在检测组件中的按键,该按键知道通过道具 currentDialog 在应用程序的其他位置当前打开了哪个对话框组件。通常,我可以通过嵌套函数访问此道具,但使用useCallback时似乎无法实现:

export const AllAreaNav = (props) => {

    console.log('AllAreaNav / props.currentDialog: ', props.currentDialog); // displays correct dialog

    const handleKeyPress = useCallback((event) => {

        console.log('AllAreaNav / handleKeyPress / props.currentDialog: ', props.currentDialog); // displays undefined
        
        if(event.keyCode === 70) {
            //Do whatever when F is pressed
            console.log("F key pressed");
            if (props.currentDialog == "DialogSearchBar") {
                // Take action based on DialogSearchBar being active
            } else {
                // Take action based on DialogSearchBar NOT being active
            }

        }

    }, []);

    useEffect(() => {
        // Listener for keypresses
        document.addEventListener("keydown", handleKeyPress, false);
        return () => {
            document.removeEventListener("keydown", handleKeyPress, false);
        };
    }, []);

    return (
        {jsxElements}
    )
};

所以现在我不太确定将其作为参数传递的简单方法-假设这将是下一步。通过研究,我相信可以在事件旁边添加另一个参数吗?该按我的预期工作:

const handleKeyPress = useCallback((event, currentDialog) => {

但是,我不完全确定如何首先将其传递给函数。如果我将侦听器修改为:

document.addEventListener("keydown", handleKeyPress(event, props.currentDialog, false);

我不确定这是否正确,或者不确定在哪种情况下以handleKeyPress默认将其定义为参数的方式来定义事件

1 个答案:

答案 0 :(得分:2)

似乎您正在尝试通过参数化回调来解决问题,但是您的上下文中没有事件。为了参数化并在上下文中包含事件,必须在currentDialog参数上创建一个闭包。

您可以尝试以下解决方案:

/**
 * move callback definition outside the component
 * and create a closure on currentDialog (function returning a function)
 */
const handleKeyPress = (currentDialog) => (event) => {
  if (event.keyCode === 70) {
    //Do whatever when F is pressed
    console.log("F key pressed");
    if (currentDialog == "DialogSearchBar") {
      // Take action based on DialogSearchBar being active
    } else {
      // Take action based on DialogSearchBar NOT being active
    }
  }
};

export const AllAreaNav = (props) => {
  console.log("AllAreaNav / props.currentDialog: ", props.currentDialog); // displays correct dialog

  useEffect(() => {
    // Listener for keypresses
    const listener = handleKeyPress(props.currentDialog); // use closure to create a callback closured on currentDialog value
    document.addEventListener(
      "keydown",
      listener,
      false
    );
    return () => {
      document.removeEventListener(
        "keydown",
        listener,
        false
      );
    };
  }, [handleKeyPress, props.currentDialog]); // pass callback and currentDialog value to dependency array

  return { jsxElements };
};