我想在用户点击某个元素时触发展开状态,但是当用户使用ref点击外部时我无法实现关闭元素。
这部分出了点问题
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();
};
控制台触发了两次。
https://codesandbox.io/s/71l34po56x
如果您只是将句柄中的expand
状态更改为true
,您可以看到几乎可以工作的结果,但我怎样才能实现2件事。
答案 0 :(得分:1)
问题是您将同一事件处理程序this->
两次附加到handleClick
(一次在div
函数中,也在render
中)。
这就是为什么当你点击componentWillMount
时,你将状态设置两次,结果div
从false变为true,然后从true变为false。
答案 1 :(得分:0)
您可以完全发出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"));
希望这对你所看到的内容有所帮助,谢谢!