简体   繁体   English

我如何在 React 的 useEffect 中安排事件

[英]How do I arrange events in useEffect in React

In main Application file (App.js) I have this code, the <button> here can unmount the "Dropdown" component在主应用程序文件(App.js)中我有这段代码,这里的<button>可以卸载“Dropdown”组件

return (
    <div>
      <button
        onClick={() => {
          console.log("App button"); // First
          setShowDropDown(!showDropDown);
        }}
      >
        Toggle Dropdown
      </button>
      {showDropDown ? (
        <Dropdown
          selected={selected}
          onSelectedChange={setSelected}
          options={options}
        />
      ) : null}
    </div>
  );

In Dropdown component file (Dropdown.js) This event onBodyClick make the Dropdown menu not active when click on any place unless the Dropdown menu itself.在 Dropdown 组件文件 (Dropdown.js) 中,此事件onBodyClick使下拉菜单在单击任何地方时不活动,除非下拉菜单本身。 The goal here is to cancel the event by Cleanup function in useEffect when I click on the button.这里的目标是当我点击按钮时通过 Cleanup function 在useEffect中取消事件。 The problem is: when I click the button, the order of what happened is something like that:问题是:当我点击按钮时,发生的事情的顺序是这样的:

  • First: The button onClick event and "unmounting".第一:按钮onClick事件和“卸载”。
  • Second: The onBodyClick event.第二: onBodyClick事件。
  • Finally: Cleanup.最后:清理。 This order makes a problem when I clicked on the button, That's because the event happening after unmounting.当我单击按钮时,此命令会出现问题,那是因为卸载后发生的事件。 How can I solve that?我该如何解决? the error: Cannot read property 'contains' of null错误:无法读取 null 的属性“包含”
  useEffect(() => {
    const onBodyClick = (event) => {
      console.log("event");   // Second
      if (ref.current.contains(event.target)) {
        return;
      }
      setOpen(false);
    };
    document.body.addEventListener("click", onBodyClick);
    return () => {
      console.log("cleanup");  // Finally
      document.body.removeEventListener("click", onBodyClick);
    };
  }, []);

Sounds like you just need to check if the ref exists first:听起来你只需要先检查 ref 是否存在:

const onBodyClick = (event) => {
  if (!ref.current) {
    // Component is unmounting
    // below line could be used or commented out; since the component is unmounting,
    // the state should not make a difference
    // setOpen(false);
    return
  }
  if (ref.current.contains(event.target)) {
    // Component is not unmounting, and click was inside ref
    return;
  }
  // Component is not unmounting, and click was outside ref
  setOpen(false);
};

I have the same problem and this is working for me我有同样的问题,这对我有用


if(this.wrapperRef && !this.wrapperRef.contains(event.target) {
 this.setState({visibility: false});
}

I check if wrapperRef exists and I check if the wrapper contains the Html element我检查 wrapperRef 是否存在,并检查包装器是否包含 Html 元素

I know you are using react hooks, but the idea is the same.我知道您正在使用 React Hooks,但想法是一样的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM