响应:当卸载了重点子组件时如何捕获重点

时间:2019-05-04 00:39:36

标签: reactjs

我有一个可以集中注意力的父级组件。它使用此焦点来提供键盘控件。该父组件可以产生一个子组件,该子组件可以类似地获得焦点,以便它可以响应键盘事件。子组件侦听的键盘事件之一是<esc>,它会导致子组件卸下。

子组件卸载后,焦点将返回到文档的<body>

我的父级组件如何检测到何时发生这种情况并将焦点重新分配给自己?

到目前为止我所知道的:

  • React的合成onBlur处理程序确实从其子级获得冒泡的模糊事件(与非合成事件不同)。但是,当具有焦点的元素离开DOM时,不会触发模糊事件。
  • React没有实现onFocusOut侦听器,但是如果我直接使用ref注册一个侦听器,则会收到一个事件,告诉我该孩子已卸载。但是,我无法区分由卸载儿童触发的focusout事件和由用户点击其他点击目标而触发的focusout事件。

编辑:我正在寻找一种不涉及父子组件之间直接通信/耦合的解决方案。想象一下,在任意深度嵌套的树中,我可能会有任意多个这样的孩子。

3 个答案:

答案 0 :(得分:1)

子组件应该接受一个函数prop,该函数在按下char compName[7]; 时(或在其他需要调用的地方)被调用。

compName[6] = '\0';

答案 1 :(得分:1)

在按下$pgggo_u_catidexclude = array_map('intval', $pgggo_u_catidexclude); foreach ($pgggo_u_catidexclude as $value) { $pgggo_u_catidexcluder[] = -1*$value; } if(is_array($pgggo_u_catidexcluder)){ $pgggo_u_catidexcluder = implode (", ", $pgggo_u_catidexcluder); }else{ $pgggo_u_catidexcluder = ''; } 键的情况下(或仅在子级的<esc>方法中),可以将回调从父级传递给要调用的子级。该回调可以将焦点转移到父对象上,就像通常发生的一样。

例如:

componentWillUnmount

答案 2 :(得分:0)

我最终使用MutationObserver解决了这个问题。

代码如下:

// It's possible for a child component to gain focus and then become
// unmounted. In that case, the browser will return focus to the `<body>`.
// In the following hook, use a `MutationObserver` to watch for that behavior
// and refocus the containing FocusTarget when it happens.
//
// I tried a number of other approaches using `focus/blur/focusin/focusout` on
// various DOM nodes, and was unable to find a solution which would trigger in
// this senario in Firefox. Therefore we use this `MutationObserver` approach.
useEffect(() => {
  // Only create the `MutationObserver` within the currently focused target.
  if (ref == null || windowId !== focusedWindowId) {
    return;
  }

  const observer = new MutationObserver(mutations => {
    // In the common case we won't have focused the body, so we can do this
    // inexpensive check first to avoid calling the more expensive `O(n)`
    // check of the individual mutations.
    if (document.activeElement !== document.body) {
      return;
    }
    if (mutations.some(mutation => mutation.removedNodes.length > 0)) {
      ref.focus();
    }
  });

  observer.observe(ref, {
    subtree: true,
    attributes: false,
    childList: true
  });

  return () => observer.disconnect();
}, [windowId, focusedWindowId, ref]);

实际提交添加:https://github.com/captbaritone/webamp/commit/2dca07ff0a97ad378a1a050513255d2ba129dbcd