2016-09-20 44 views
3

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

考虑一个Widget组件。

我希望能够关注某些元素,并根据键盘快捷键在此组件上运行函数。

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

setBindings和removeBindings,将使用图书馆像mousetrap绑定特定的键盘快捷键

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

  1. 这使得键盘快捷键的行为不可预测
    • 考虑两个小工具挂载的情况,其中一个会覆盖另一个
  2. Widget与快捷键紧密结合 - 现在如果有人不想使用快捷键,他们必须在Widget上有某种标志。这种破坏是该代码的“粒度” - 理想用户应该能够使用的Widget,然后WidgetWithShortcuts,或像这样

另一个潜在的解决方案,是通过一个实例

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

与第二个解决方案的问题是:

  1. widgetInstance将不得不暴露了很多公开访问的方法,如focusSomeThing,或invokeProp等

  2. 如果Widget想要提供一些工具提示,即在某些地方显示键盘快捷方式,有关键盘快捷键的信息将在不同的地方复制。这将有可能改变一个地方的捷径,而忘记了在另一个地方

是否有一个最佳实践,或者对如何键盘快捷键可以与上述问题的解决方案来实现一些想法,这样做呢?

回答

1

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

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

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

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

那么你的widget可以反应(或不反应)的道具变化:

class Widget extends Component { 
    ... 

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

    ... 
} 

如果你传递的快捷托了许多组件可能是值得投入的快捷状态进入上下文。

+0

不错的主意!谢谢azium:) –