skip to Main Content
let inner=useRef();
  let inner_exit=useRef();
  useEffect(()=>{
    inner.current=document.querySelectorAll('.inner');
    inner_exit.current=document.querySelectorAll('.exit');
    
     inner_exit.current?.[0].addEventListener("click",toogleInner);
    inner.current?.[0].addEventListener("click",(e)=>{
      if(e.target === e.currentTarget) toogleInner();
    });
    
  },)
  const toogleInner = ()=>{
    inner.current?.[0].classList.toggle('hide');
  };
 
    return (
    <div className='inner'>
      <div className='contentSign'>
        <div className='form'>
        <h2>Đăng nhập</h2>
        <span className='exit'>X</span>
      </div>
    </div>  
  )    
};

I want when i click on space or tag span "X" tag div class "inner" to be hide, but when I click it, it re-renders twice. I find many ways, like: useCallBack, use Memo, but I don’t know how to use them for my code.Can you fix it for me, please?

I don’t know how to fix this bug

2

Answers


  1. It looks like there are a few issues in your code. Here’s a revised version using useCallback and useEffect to handle the event listeners more efficiently:

    import React, { useEffect, useRef, useCallback } from 'react';
    
    const YourComponent = () => {
      const inner = useRef(null);
      const innerExit = useRef(null);
    
      const toggleInner = useCallback(() => {
        inner.current?.classList.toggle('hide');
      }, []);
    
      useEffect(() => {
        inner.current = document.querySelector('.inner');
        innerExit.current = document.querySelector('.exit');
    
        const handleClickExit = () => {
          toggleInner();
        };
    
        const handleClickInner = (e) => {
          if (e.target === e.currentTarget) {
            toggleInner();
          }
        };
    
        innerExit.current?.addEventListener('click', handleClickExit);
        inner.current?.addEventListener('click', handleClickInner);
    
        return () => {
          innerExit.current?.removeEventListener('click', handleClickExit);
          inner.current?.removeEventListener('click', handleClickInner);
        };
      }, [toggleInner]);
    
      return (
        <div className='inner'>
          <div className='contentSign'>
            <div className='form'>
              <h2>Đăng nhập</h2>
              <span className='exit'>X</span>
            </div>
          </div>
        </div>
      );
    };
    
    export default YourComponent;
    

    This version uses useCallback to memoize the toggleInner function and ensures proper cleanup of event listeners using the cleanup function returned by useEffect.

    Login or Signup to reply.
  2. This is poor react. It is not common to use direct DOM APIs to add event listeners in react (it’s not forbidden, just not the norm).

    Also, the "number of renders" is almost never something you should ever be concerned about. You should also never try to optimize performance if you don’t have a performance problem (or imminently foresee one)

    Trying to avoid the render defeats the entire purpose of using react for it’s ability to provide simplicity and rapid development.

    Writing code like you have above will not improve your React skills.

        const [isVisible,setIsVisible] = useState(true)
     
        return (
          <div className={`inner ${isVisible ? '' : 'hide'}`}>
            <div className='contentSign'>
              <div className='form'>
              <h2>Đăng nhập</h2>
              <span className='exit' onClick={() => setIsVisible(false)}>X</span>
            </div>
          </div>  
        )    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search