在 React 中单击组件外部时更改状态
Posted
技术标签:
【中文标题】在 React 中单击组件外部时更改状态【英文标题】:Change the state when clicking outside a component in React 【发布时间】:2018-07-18 08:37:42 【问题描述】:我有一个下拉菜单,如下图所示:
当我单击文件夹图标时,它会打开和关闭,因为 showingProjectSelector
属性处于设置为 false 的状态。
constructor (props)
super(props)
const organization, owner, ownerAvatar = props
this.state =
owner,
ownerAvatar,
showingProjectSelector: false
当我单击该图标时,它会正确打开和关闭。
<i
onClick=() => this.setState( showingProjectSelector: !this.state.showingProjectSelector )
className='fa fa-folder-open'>
</i>
但是我想要做的是在我点击下拉菜单时关闭它。我如何在不使用任何库的情况下做到这一点?
这是整个组件:https://jsbin.com/cunakejufa/edit?js,output
【问题讨论】:
***.com/questions/32553158/… github.com/Pomax/react-onclickoutside 我已经在多个项目中使用过这个包,它可以完美运行:npmjs.com/package/react-onclickoutside 希望这能帮助stackblitz.com/edit/react-vzhmj7我为弹出框做的,在你的场景中像这样使用 【参考方案1】:您可以尝试利用 onBlur
:
<i onClick=... onBlur=() => this.setState(showingProjectSelector: false)/>
【讨论】:
感谢您的回答!它没有工作,我不知道为什么:(【参考方案2】:我遇到了同样的问题。阅读后解决: Detect click outside React component 请尝试:
【讨论】:
【参考方案3】:您应该使用高阶组件来包装您想要在其外部监听点击的组件。
这个组件示例只有一个 prop:“onClickedOutside”,它接收一个函数。
ClickedOutside.js
import React, Component from "react";
export default class ClickedOutside extends Component
componentDidMount()
document.addEventListener("mousedown", this.handleClickOutside);
componentWillUnmount()
document.removeEventListener("mousedown", this.handleClickOutside);
handleClickOutside = event =>
// IF exists the Ref of the wrapped component AND his dom children doesnt have the clicked component
if (this.wrapperRef && !this.wrapperRef.contains(event.target))
// A props callback for the ClikedClickedOutside
this.props.onClickedOutside();
;
render()
// In this piece of code I'm trying to get to the first not functional component
// Because it wouldn't work if use a functional component (like <Fade/> from react-reveal)
let firstNotFunctionalComponent = this.props.children;
while (typeof firstNotFunctionalComponent.type === "function")
firstNotFunctionalComponent = firstNotFunctionalComponent.props.children;
// Here I'm cloning the element because I have to pass a new prop, the "reference"
const children = React.cloneElement(firstNotFunctionalComponent,
ref: node =>
this.wrapperRef = node;
,
// Keeping all the old props with the new element
...firstNotFunctionalComponent.props
);
return <React.Fragment>children</React.Fragment>;
【讨论】:
【参考方案4】:如果你想使用一个已经存在的小组件(466 字节压缩)来实现这个功能,那么你可以查看这个库react-outclick。
该库的好处在于它还可以让您检测组件外部和另一个组件内部的点击。它还支持检测其他类型的事件。
使用该库,您可以在组件中拥有类似的内容。
import OnOutsiceClick from 'react-outclick';
class MyComp extends Component
render()
return (
<OnOutsiceClick
onOutsideClick=() => this.setState(showingProjectSelector: false)>
<Dropdown />
</OnOutsiceClick>
);
【讨论】:
【参考方案5】:包装组件 - 即包装所有其他组件的组件
创建运行函数 handleClick 的 onClick 事件。
handleClick 函数检查点击事件的 ID。
当 ID 匹配时,它会做一些事情,否则它会做其他事情。
const handleClick = (e) =>
if(e.target.id === 'selectTypeDropDown')
setShowDropDown(true)
else
setShowDropDown(false);
所以我有一个下拉菜单,只有当你点击下拉菜单时才会出现,否则它会隐藏它。
【讨论】:
以上是关于在 React 中单击组件外部时更改状态的主要内容,如果未能解决你的问题,请参考以下文章