【问题标题】:Avoid multiple events on a dropdown: ReactJS避免下拉列表中的多个事件:ReactJS
【发布时间】:2020-07-22 07:00:06
【问题描述】:

我正在尝试处理复选框内的树。我正在使用 onClick、onClose 和 onOpen 来实现下拉菜单的打开。但是当点击语义-ui-react 时不知何故 onclick 和 onclose。有人可以帮我实现这一目标吗?

点击下拉菜单时,它应该打开下拉菜单,然后切换它,无论何时进行树更改,它都应该打开。

https://codesandbox.io/s/semantic-ui-react-yzemk?file=/index.js

import React from "react";
import { render } from "react-dom";
import { Dropdown } from "semantic-ui-react";
import CheckboxTree from "react-checkbox-tree";
import "react-checkbox-tree/lib/react-checkbox-tree.css";
const nodes = [
  {
    value: "mars",
    label: "Mars",
    children: [
      { value: "phobos", label: "Phobos" },
      { value: "deimos", label: "Deimos" }
    ]
  }
];

class App extends React.Component {
  state = {
    checked: [],
    expanded: [],
    options: [],
    open: false
  };

  onClose = e => {
    console.log("on close");
    this.setState({ open: true });
  };

  onOpen = e => {
    console.log("on open");
    this.setState({ open: true });
  };

  onChange = e => {
    console.log("on change");
    e.stopPropagation();
    this.setState({ open: true });
  };

  onClick = e => {
    console.log("on click");
    e.stopPropagation();
    this.setState({ open: !this.state.open });
  };

  render() {
    return (
      <div>
        <Dropdown
          className="icon"
          selection
          options={this.state.options}
          text="Select"
          open={this.state.open}
          onClose={this.onClose}
          onOpen={this.onOpen}
          onChange={this.onChange}
          onClick={this.onClick}
        >
          <Dropdown.Menu>
            <Dropdown.Item>
              <CheckboxTree
                nodes={nodes}
                checked={this.state.checked}
                expanded={this.state.expanded}
                onCheck={checked =>
                  this.setState({ checked }, () => {
                    console.log(this.state.checked);
                  })
                }
                onExpand={expanded => this.setState({ expanded })}
              />
            </Dropdown.Item>
          </Dropdown.Menu>
        </Dropdown>

      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

【问题讨论】:

  • 那么你想要的行为是什么?因为,沙箱中的代码运行良好
  • 点击应该切换下拉切换

标签: javascript reactjs ecmascript-6 setstate semantic-ui-react


【解决方案1】:

如果我理解正确,您遇到了下拉菜单未关闭的问题,我在您的代码中看到您在 onClose 中将 open 设置为 true。

onClose = e => {
    console.log("on close");
    this.setState({ open: false }); // this is `true` in your code
  };

作为进一步的建议,当您使用现有状态来修改状态时,请在 setState 中使用 callback function

// this.setState({ open: !this.state.open }); don't use this
this.setState((prevState)=>{
  return {
    open: !prevState.open,
  };
});

【讨论】:

  • 但在复选框内选择某些内容时,它会关闭。我希望它保持开放。只有单击下拉菜单才能打开/关闭
  • 我不知道 Dropdown 组件的内部实现,但是当您单击 &gt; 时,似乎调用了关闭下拉菜单的模糊事件。单击复选框时不会发生这种情况。因此,您可以检查该代码并添加适当的 e.stopPropagation() 以不关闭下拉列表
【解决方案2】:

您的 OnClick 方法会在每次单击元素时更改 state.open - 即使您单击内部元素也是如此。 这就是关闭下拉菜单的原因。

--

我认为这就是您想要的,尽管我认为这不是最优雅的解决方案:

import React from "react";
import { render } from "react-dom";
import { Dropdown } from "semantic-ui-react";
import CheckboxTree from "react-checkbox-tree";
import "react-checkbox-tree/lib/react-checkbox-tree.css";
const nodes = [
  {
    value: "mars",
    label: "Mars",
    children: [
      { value: "phobos", label: "Phobos" },
      { value: "deimos", label: "Deimos" }
    ]
  }
];

class App extends React.Component {
  state = {
    checked: [],
    expanded: [],
    options: [],
    open: false
  };
/*
  onClose = e => {
    console.log(e.target)
    ///if(e.target.role==="listbox"){
      console.log("on close");
      this.setState({ open: false }); // this is `true` in your code  
    //}
};
  onOpen = e => {
    console.log("on open");
    this.setState({ open: true });
  };
  
  onChange = e => {
    console.log("on change");
    this.setState({ open: true });
  };*/
  onClick = e => {
    if(e.target.id==="dropdown" || e.target.className==="text" || e.target.className==="dropdown icon"){
      this.setState({ open: !this.state.open });
    }
    console.log("on click");
  };

  render() {
    return (
      <div>
        <Dropdown
          id="dropdown"
          className="icon"
          selection
          options={this.state.options}
          text="Select"
          open={this.state.open}
          onClose={this.onClose}
          onOpen={this.onOpen}
          onChange={this.onChange}
          onClick={this.onClick}
        >
          <Dropdown.Menu>
            <Dropdown.Item>
              <CheckboxTree
                nodes={nodes}
                checked={this.state.checked}
                expanded={this.state.expanded}
                onCheck={checked =>
                  this.setState({ checked }, () => {
                    console.log(this.state.checked);
                  })
                }
                onExpand={expanded => this.setState({ expanded })}
              />
            </Dropdown.Item>
          </Dropdown.Menu>
        </Dropdown>

        {/* <CheckboxTree
          nodes={nodes}
          checked={this.state.checked}
          expanded={this.state.expanded}
          onCheck={checked => this.setState({ checked })}
          onExpand={expanded => this.setState({ expanded })}
        /> */}
      </div>
    );
  }
}

render(<App />, document.getElementById("root"));

【讨论】:

  • 我确实尝试注释掉 onClick 方法中的代码,但这似乎并不能解决问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
  • 2013-10-11
  • 2021-01-23
相关资源
最近更新 更多