Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/476.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在其他元素/主体处单击时,反应切换和关闭失败_Javascript_Reactjs_Dom Events - Fatal编程技术网

Javascript 在其他元素/主体处单击时,反应切换和关闭失败

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

我想在用户单击某个元素时触发展开状态,但当用户使用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();
  };
控制台触发了两次

如果您只需在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本身