首页 > 解决方案 > 反应条件使用效果

问题描述

我正在创建一个处理程序来观察组件外部的点击(点击文档)。

如果myCondition === true每次点击都做一些事情,否则忽略点击。

问题是:我应该在每次更改时
添加/删除- 还是 - 只需将语句放在? 哪个更受欢迎?为什么?handleClickmyCondition

ifhandleClick

请参阅下面的代码:

const [myCondition, setMyCondition] = useState<boolean>(false);

useEffect(() => {
    if (!myCondition) return;
    
    
    const handleClick = () => {
        // do some stuff ...
    }
    
    
    /* if meets the `myCondition` => attach the `handleClick`, otherwise detach it */
    
    // setups:
    document.addEventListener('click', handleClick);
    
    // cleanups:
    return () => {
        document.removeEventListener('click', handleClick);
    };
}, [myCondition]);


const myConditionRef = useRef<boolean>(myCondition);
myConditionRef.current = myCondition;
useEffect(() => {
    const myCondition2 = myConditionRef.current;
    if (!myCondition2) return;
    
    const handleClick = () => {
        /* if meets the `myCondition` => do it, otherwise ignore */
        if (!myCondition2) return;
        
        // do some stuff ...
    }
    
    
    // setups:
    document.addEventListener('click', handleClick);
    
    // cleanups:
    return () => {
        document.removeEventListener('click', handleClick);
    };
}, []);

注意:我将 包装myCondition到 中,useRef因此myCondition可以在第二个中使用,useEffect 而不会在依赖数组中列出。

标签: reactjsreact-hooksuse-effect

解决方案


如果要在 useEffect 中使用条件更改,请在 useEffect 中声明一个函数。对于您的组件,您需要在函数内捕获事件并检查当前和 event.target。并根据您的需要更改任何状态。

const Action = ( {}) => {
  const ref = useRef();
 const [show, setShow] = useState();

  useEffect(() => {
    const listener = (event) => {
      if (!ref.current || ref.current?.contains(event.target)) {
        return;
      }
      console.log("clicked outside of the component");
      setShow(false);
    };

    document.addEventListener("click", listener);

    return () => {
      document.removeEventListener("click", listener);
    };
  }, [ref]);

  return (
    <span ref={ref}>
    <span onClick={(_) => setShow(!show)}>
       Action
    </span> 
    {show && (
        <div>
          <span
            onClick={() => {
              setShow(false);
            }}
          >
            Select
          </span>
        </div>
      )}
    </span>
  );
};

推荐阅读