• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 React 게시판 검색창을 만드는 도중 바깥창을 클릭시

검색창을 만드는 도중 바깥창을 클릭시

9 글 보임 - 1 에서 9 까지 (총 9 중에서)
  • 글쓴이
  • #29899

    오진희
    참가자

    검색창을 만드는 도중 검색창을 감싸는 박스dvi를 클릭시

    검색이 펼쳐지구, 바깥창 영역을 클릭시 검색창이 닫아지도록 계획하고있습니다.

    그래서 구글검색 으로 찾아서 적용한 코드가 아래

    function 검색창 (){

         let [big_status, setbig_status] = useState(false);

         let ref = useRef();

         let ClickOutside = (e) => {
          //    console.log(e.target);        
                 if (big_status && !ref.current.contains(e.target)) setbig_status(false);                
         };

         useEffect(() => {
              window.addEventListener("click", ClickOutside);
              return () => {
                    window.removeEventListener("click", ClickOutside);
               }
          }, [big_status]);

     

     return (
            <div id='seach_input' ref={ref} onClick={() => {setbig_status(true);}}  // true로  바뀜.
                   className={ big_status ? 'ext': null } >   
               <input id="search_i" placeholder="mall에있는상품,영화 찾아드릴게요!"

                 className={ big_status ? 'ext2': null }   onChange={ (e) => { setText(e.target.value); } } />
               <button className="anybt" type="submit" onClick={search_item} >검색</button>
              생략...

      );

    }

     

    대략 이런식으로 코드짜서 만들어서 구현은 다했습니다. 문제가 ....

    펼쳐져서 검색 기능까지 다 잘되고, 현재컴포넌트위치에서  바깥 창 영역을 클릭시 검색창이 다시 원상태로 돌아가고 잘되는데 ,

    이게  만약 검색창이 펼쳐진상태에서  바깥창 영역에 보이는 상품창을 잘못클릭하여 상품 상세페이지로 라우팅되어 이동 하면, 에러가 뜨면서 안보입니다... 

    "Uncaught TypeError: Cannot read properties of null (reading 'contains') "이케요...

    그래서 저는 null이 라구 떠서 안되는건가 싶어서 이부분 코드를 

     

     let ClickOutside = (e) => {
           //    console.log(e.target);
            if(e.target !== null ){
                  if (big_status && !ref.current.contains(e.target)) setbig_status(false);
            }                
      }; 이렇게 null이 아닐때만  동작하게 해주세요. 라고 해봤는데도 ...안되더라구요 ....

    제생각 으로는 라우팅 되어 페이지 이동시에만  저기 ref.current를 케치 못하는듯합니다...

    어떻게 수정해야 동작할지 계속 고민을 해도 ....해결이 되지 않아서 쌤의 도움이 필요합니다....

    쌤께서는 이런경우 어떻게 해결 하시나요?......ㅠㅠ. 감사합니다!

     

    #29925

    codingapple
    키 마스터

    바깥영역을 검은 반투명 배경같은 div박스로 만들면 됩니다 그럼 뒤에 상품 안눌릴듯요

    #29929

    오진희
    참가자

    앗!처음에 그방법도 고려해봤었는데 혹시 기존 위에 코드에서도 안눌리는 방법이 있나 고민을계속 했었습니다 ㅠㅠ

    저기 검색창에서 아이템을 검색하면 나오는  목록을 클릭하면 그해당 페이지로 이동을 하거든요 ...

    그럼 또 에러가 생겨서 ㅠㅠ 안되겠더라구요.

    그래서 쌤 말씀데로 뒤에 반투병back 넣었습니다.

    그리고 한가지더 질문이 있습니다 ㅠㅠ... 이거또한 하다가 갑자기 ....

    에러가....  다른 컴포넌트에서는 분명 됬던 것인데

    app컴포넌트, 메인컴포넌트에서  useEffect()안에 스크롤 이벤트를 넣어서 

    어느 위치에 오면 어떤 애니메이션을 넣었습니다. 

     

    let cienema_ref  =  useRef();

    이것또한 메인페이지 에서 잘되다가 , 다른 페이지 이동을 하게 되면 마찬가지로 

    이런 Uncaught TypeError: Cannot read properties of null , offsetTop을 읽을수없다는

    이 에러가 나오더라구요 ....ㄷㄷㄷ..

    컴포넌트 나갈때 cleanup 평션에도 이벤트  remove 처리를 했는뎅.....

    저기 cinema_ref.current를 또 못읽나 봅니다....왜 이런 에러가...나는지 ㅠㅠ 알수가....

    다른 컴포넌트에서 사용했을경우  클릭할때  let maptop =  any_ref.current.offsetTop ;구해서 변수에 넣어 => 해당위치로  이동하는 

     window.scrollTo({top:maptop }); 이런식으로 했을경우 잘 작동하고 컴포넌트 사라질때도 에러가 없었는데 ....

    어째서 .....저기서는 에러가 나는걸까요?ㅠㅠㅠ샘 ......어떻게 해야..해결이 될까요?.....

     

     

     

    #29944

    codingapple
    키 마스터

    함수정의는 useEffect 바깥에 만드는게 좋습니다 if문으로 cinema_ref가 있으면 코드실행해달라고 처리해도 될듯요 

     

    #29972

    오진희
    참가자

    아~~!!!!!함수를 useeffect 밖에서 정의하고  호출하면되군요!! 알겠습니당!! 감사합니다 쌤!~아항!!~~
    혹시  그이유도  알려주실수 있을카요? ㅎㅎ ㅎ

    #29991

    codingapple
    키 마스터

    여러번 실행될까봐 그런건데 1번만 실행되면 useEffect 안에서 함수만들어도 될거같긴하군요 

     

    #29995

    오진희
    참가자

    애쁠샘.....우선  여러번 여쭤 봐서 죄송합니다... ㅠㅠ

    쌤께서 알려주신 방법 으로  function 밖으로 꺼내서

    function app_scroll (){

         if(cinema_ref){  
                let cinema_top = cinema_ref.current.offsetTop;

                if(window.pageYOffset > cinema_top ){
                    toggleconchan(true);
                    생략... 
                }

    }

     

    적용하구  현재 컴포넌트에서는 잘되는데 ... 마찬가지로 페이지 이동하면 

    똑같은 에러가 ... Uncaught TypeError: Cannot read properties of null (reading 'offsetTop') 나와요....

    흑 ㅠㅠ.....

    혹시  컴포넌트 위치 때문일까요?..현재 <Route exact path="/"> 메인컴포넌트를 따로 꺼내서 만들지 않고  "/" Route 안에  바로< div></div> 통째로 들어가있습니다.  아래처럼요.. 혹시 이때문일까요?

    메인페이지의 해당  스크롤이벤트가 들어가있는 useEffect()를 바로App컴포넌트에 만들어져 있어서 이러 에러가 뜨는걸까요?...

     

    function App(){

         let cinema_ref = useRef(null); 

         생략....

        let app_scroll = () => {  
            if(cinema_ref){  
                 let cinema_top = cinema_ref.current.offsetTop;

                 if(window.pageYOffset > cinema_top){
                       toggleconchan(true);
                       생략...
                  }
             }
        }
       
        useEffect( () => {     
              if(cinema_ref){
                   window.addEventListener('scroll', app_scroll);    
               }  

            return () => {            
                   window.removeEventListener('scroll', app_scroll);  
                
            }  
        }, []);  

        생략....

       return(

          <div className="App">

             <Navbar bg="light" expand="lg" className="navjin" >

            </Navbar>

          <Switch>

              <Route exact path="/">

                    <div id="jinwrap">

                       생략,,,,

                      <div id="jinhee" ref={cinema_ref}>

                          시네마

                       </div>생략...

                    </div>

              </Route>

              <Route exact path="/다른거1">

                  <다른컴포넌트1 />

              </Route>       

              <Route exact path="/다른거2">

                  <다른컴포넌트2 />

              </Route>

          </Switch>

            이런식으로 쭉되어있습니다.

        </div>

     

       );

    }

    export default App;

     

    메인페이지 컴포넌트가 따로 분리가 안되어 있어서 이런 에러가 뜨는걸까요?....

    #30013

    오진희
    참가자

    컴포넌트 따로 빼서 시도 해봤지만... 마찬가지로 안되네융 ....흑.... 페이지 이동만  하면  저에러가 뜨네용....흑 ....  대체 이유가 ㅠㅠ.....에러야....왜뜨는거니.....if문으로 나오지말라고 까지 했는데.... 

    #30024

    codingapple
    키 마스터

    현재 App컴포넌트에서 벗어날 일이 없으니 useEffect 안의 return문은 실행되지않을 것 같군요 

    다른페이지에서 그 UI가 필요없으면 <Route exact path="/"> 안에 있는 내용을 컴포넌트로 묶고 그거 안에서 useEffect쓰거나 그래봅시다

9 글 보임 - 1 에서 9 까지 (총 9 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관, 개인정보처리방침
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠