我想在 React 中做一个下拉菜单。单击一个按钮应打开一个子菜单。在子菜单之外单击应将其关闭
Posted
技术标签:
【中文标题】我想在 React 中做一个下拉菜单。单击一个按钮应打开一个子菜单。在子菜单之外单击应将其关闭【英文标题】:I want to make a dropdown in React. Clicking a button should open a submenu. Clicking outside of the submenu should close it 【发布时间】:2016-02-29 15:27:22 【问题描述】:这是我现有的工作代码。这很好用,除了如果我在子菜单之外单击,当它打开时,子菜单保持打开状态。
class UserTypeDropdown extends React.Component
constructor: (props) ->
super(props)
@state =
display_submenu: false
@propTypes:
selected: React.PropTypes.string.isRequired
submenu_display:->
if @state.display_submenu
'block'
else
'none'
button_class_names:->
classNames(
'select-btn ': true,
'user_role ': @props.selected is 'user',
'admin_role ': @props.selected is 'admin'
)
selected_text:->
if @props.selected == 'user'
'User'
else
'Administrator'
render:->
div className: 'user-type-dropdown',
button className: @button_class_names(), onClick: @_toggleSubmenu ,
@selected_text()
ul className: 'submenu submenu_content access_submenu', style: display: @submenu_display(),
li onClick: @select_admin,
a ,
'Administrator'
li onClick: @select_user,
a ,
'User'
_toggleSubmenu: =>
@setState display_submenu: !@state.display_submenu
select_admin: =>
@_toggleSubmenu()
actions.setUserRole('admin')
select_user: =>
@_toggleSubmenu()
actions.setUserRole('user')
我想实现在子菜单打开时单击外部,然后将其关闭。
我已经阅读了如何在 React 中执行此操作,并且遇到了很多建议说我应该使用 onFocus 和 onBlur 而不是 onClick
这对我来说很有意义,因为这意味着下拉菜单应该只有在浏览器中处于焦点时才应该打开。所以我的渲染函数和方法就变成了。
render:->
div className: 'user-type-dropdown',
button className: @button_class_names(), onFocus: @_toggleSubmenu, onBlur: @_toggleSubmenu ,
@selected_text()
ul className: 'submenu submenu_content access_submenu', style: display: @submenu_display(),
li onClick: @select_admin,
a ,
'Administrator'
li onClick: @select_user,
a ,
'User'
_toggleSubmenu: =>
@setState display_submenu: !@state.display_submenu
select_admin: =>
actions.setUserRole('admin')
select_user: =>
actions.setUserRole('user')
但是在 button
元素上使用 onFocus:
和 onBlur:
,
现在点击li
中的任何一个都不会触发@select_admin
或@select_user
,它只会触发@_toggle_submenu
,并且点击似乎不会传播/冒泡到下面的li
元素。。
通过阅读React Event Documentation 和This Focus and hotkeys guide,我可以看到这些事件应该会冒泡,但对我来说根本不是。
我是 React Coffescript/JS 世界的新手,所以请原谅任何不正确的命名约定。
我认为我的理解一定有缺陷,因为我在任何地方都找不到这个问题的答案。
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:您的问题是:一旦您单击一个项目,onBlur 事件就会首先触发。这会导致重新渲染(因为您执行setState
)。因此,您的 onClick 事件永远不会运行。
解决这个问题的方法(使用 onFocus 和 onBlur)是重新排列您的 html 设置:
确保您的主菜单项能够获得焦点(<button>
已经可以了)
确保您的子菜单没有焦点(<li>
可以)
确保您的子菜单位于主菜单组件内(您需要更改此设置)
这样,如果您单击其中一个子项,您的主菜单项就不会失去焦点。
您可以找到一个简单的(仅限 HTML 和 javascript)JSBIN example here。
【讨论】:
这很有意义。我从我们之前的非反应设计中继承了 html 结构,并且从未想过要更改它。明天我会更新结构,让你知道我的进展如何!谢谢:) 效果很好,非常感谢@wintvelt!以上是关于我想在 React 中做一个下拉菜单。单击一个按钮应打开一个子菜单。在子菜单之外单击应将其关闭的主要内容,如果未能解决你的问题,请参考以下文章