8

在 Web 应用程序中管理键盘快捷键有点棘手。

考虑一个Widget组件。

我希望能够基于键盘快捷键聚焦某些元素,并在该组件上运行功能。

class Widget extends React.Component {
  componentDidMount() {
    this.setBindings()
  },
  componentWillUnmount() {
    this.removeBindings();
  }
} 

setBindings 和 removeBindings,将使用诸如mousetrap之类的库来绑定特定的键盘快捷键

现在,上述解决方案存在两个问题:

  1. 它使键盘快捷键行为不可预测
    • 考虑安装两个小部件的情况,一个会覆盖另一个
  2. 小部件与快捷方式紧密耦合——现在如果有人不想使用快捷方式,他们必须在Widget. 这破坏了代码的“粒度”——理想情况下,用户应该能够使用 Widget,然后是 WidgetWithShortcuts,或者类似的东西

另一个潜在的解决方案是传递一个实例

const widgetShortcuts = (widgetInstance) => {
  return {
   'ctrl i': () => widgetInstance.focusInput(),
  }
}

第二种解决方案的问题是:

  1. widgetInstance 将不得不公开许多可公开访问的方法,例如 focusSomeThing 或 invokeProp 等

  2. 如果Widget想要有一些工具提示,在某些地方显示键盘快捷键,则有关键盘快捷键的信息将在不同的地方重复。可以在一个地方更改快捷方式,而在另一个地方忘记这样做

是否有最佳实践,或者关于如何通过解决上述问题来实现键盘快捷键的一些想法?

4

2 回答 2

4

React-hotkeys不是一种方法,而是一种听起来可以解决您面临的问题的工具。

需要注意的一些事项:

  • 您可以通过将组件包装在<HotKeys>附加了热键的自定义组件中来使用它。
  • 方法不公开,而是通过keymap&分配给热键handler
  • 添加到子组件的热键将优先于父组件热键

我在使用这个插件时遇到的一个问题是,似乎没有一种方法可以在输入输入字段时阻止热键触发,但除此之外它似乎工作得很好。

于 2018-08-30T18:56:23.043 回答
1

我认为您最好的选择是在顶层设置一次键盘快捷键侦听器,并将信息传递给可能会或可能不关心快捷键发生的组件。这解决了问题 1,您可以多次绑定侦听器,并且这也排除了公开任何组件函数的需要。

class ShortcutProvider extends Component {
   state = { shortcut: null }

   componentDidMount() {
     // shortcut library listener
     onShortcut(shortcut => this.setState({ shortcut })
   }

   render() {
     <App shortcut={this.state.shortcut} />
   }
}

然后您的小部件可以对道具更改做出反应(或不做出反应):

class Widget extends Component {
  ...

  componentWillReceiveProps(nextProps) {
    if (this.state.shouldReactToShortcut) {
      if (nextProps.shortcut === 'ctrl i') {
        // do something
      }
    }
  }

  ...
}

如果您将快捷方式道具传递给许多组件,那么将快捷方式状态放入上下文中可能是值得的。

于 2016-09-20T22:51:28.843 回答