Javascript 在其他元素/主体处单击时,反应切换和关闭失败
我想在用户单击某个元素时触发展开状态,但当用户使用ref在外部单击时,我无法实现关闭该元素 这部分有问题:Javascript 在其他元素/主体处单击时,反应切换和关闭失败,javascript,reactjs,dom-events,Javascript,Reactjs,Dom Events,我想在用户单击某个元素时触发展开状态,但当用户使用ref在外部单击时,我无法实现关闭该元素 这部分有问题: handleClick = e => { if (this.node.contains(e.target)) { this.setState({ expand: !this.state.expand // doesn't work? },()=>console.log(this.state.expand)); ret
handleClick = e => {
if (this.node.contains(e.target)) {
this.setState({
expand: !this.state.expand // doesn't work?
},()=>console.log(this.state.expand));
return;
}
this.handleClickOutside();
};
控制台触发了两次
如果您只需在handleClick中将expand
的状态更改为true
,您可以看到几乎正常工作的结果,但我如何实现两件事呢
问题是您将同一事件处理程序
handleClick
两次附加到div
(一次在render
函数中,另一次在componentWillMount
中)
这就是为什么当您单击
div
时,会设置两次状态,结果expand
从false变为true,然后从true变为false 您可以同时发出componentWillMount()和componentWillUnmount函数。然后,当单击div时,切换功能可以完美地工作。这里缺少的是,当在div之外进行单击时,clickhandler()不再附加到此div,而是被单击的根div
为了克服这个问题,我添加了一个父div,以占据最大高度,然后使用单击处理程序展开并切换div值
下面是代码片段
import React, { Component } from "react";
import { render } from "react-dom";
const styles = {
fontFamily: "sans-serif",
textAlign: "center",
border: "2px solid red",
height: "500px"
};
const styles2 = {
fontFamily: "sans-serif",
textAlign: "center",
border: "2px solid black"
};
export default class App extends Component {
state = {
expand: false
};
expandedArea() {
return <div>content area</div>;
}
handleClickOutside = () => {
this.setState({
expand: false
});
};
handleClick = e => {
console.log("ddd");
e.stopPropagation();
if (this.node.contains(e.target)) {
this.setState({
expand: !this.state.expand // doesn't work?
});
return;
}
this.handleClickOutside();
};
render() {
const { expand } = this.state;
return (
<div style={styles} onClick={e => this.handleClickOutside(e)}>
<div
style={styles2}
ref={node => (this.node = node)}
onClick={e => this.handleClick(e)}
>
hello world
{expand && this.expandedArea()}
</div>
</div>
);
}
}
render(<App />, document.getElementById("root"));
import React,{Component}来自“React”;
从“react dom”导入{render};
常量样式={
fontFamily:“无衬线”,
textAlign:“居中”,
边框:“2件纯红”,
高度:“500px”
};
常量styles2={
fontFamily:“无衬线”,
textAlign:“居中”,
边框:“2件纯黑”
};
导出默认类应用程序扩展组件{
状态={
扩展:false
};
扩展区域(){
返回内容区;
}
handleClickOutside=()=>{
这是我的国家({
扩展:false
});
};
handleClick=e=>{
控制台日志(“ddd”);
e、 停止传播();
if(this.node.contains(e.target)){
这是我的国家({
展开:!this.state.expand//不工作?
});
回来
}
这个.handleClickOutside();
};
render(){
const{expand}=this.state;
返回(
此.handleClickOutside(e)}>
(this.node=node)}
onClick={e=>this.handleClick(e)}
>
你好,世界
{expand&&this.expandedArea()}
);
}
}
render(,document.getElementById(“根”));
希望这对你所看到的有帮助,谢谢
这个
不是您在使用箭头(=>)
函数时所认为的那样,该示例似乎没有显示展开的区域。@Colin如果您执行this.setState({expand:true})
您可以看到它。这是您想要的吗@科林:没错,你改变了什么?但是等等,它失去了切换功能。有什么解决方案吗?我也知道这个问题。这不是解决这个问题的最优雅的方法,但类似的方法可以解决这个问题。我所做的是在文档(或div外部)附加一个不同的事件处理程序,以检查单击的元素不是div本身