리액트-n초 지나면 메시지창 없애기 with useEffect( )

Wonju·2022년 2월 1일
0

이전에 UI 모달창 클릭할때마다 없애고 띄우고 했던 방법을 활용한다.

function Detail(){
 let [alert, setAlert] = useState(true);
  
   useEffect(() => {
    let 타이머 = setTimeout(() => {
      setAlert(!alert);
    }, 2000);
  });  
}

return (
  <div>
  {alert === true ? (
        <div className="my-alert2">
          <p>재고가 얼마 남지 않았습니다</p>
        </div>
      ) : null}
  </div>)
}
  1. [alert, setAlert] 라는 상태(UI가 보이고 안보이고)를 만들고 기본값을 true로 잡는다.
  2. 삼항조건연산자 를 이용해 state가 true일땐 창을 보이게 하고, false이면 보이지 않는 조건문을 만든다. (리액트에선 if문 사용 X)
  3. useEffect() 에 콜백함수를 넣고, 그것은 setTimeout이다.
  4. n초뒤 실행할 setAlert 를 setTimeout의 콜백함수로 넣는다.
  5. useEffect()는 2초가 지나면 !alert상태가 되도록 만든다.

컴포넌트가 업데이트될때마다 useEffect가 실행된다?

useEffect는 컴포넌트가 첫등장+업데이트 될때마다 실행된다.
눈으로 직접 보기 위해 <input/>태그를 추가하고, [input, setInput]이라는 state를 추가, 문자가 input태그에 입력될때마다 input 이라는 state에 저장되도록 만든다. 그리고 그 데이터가 눈에 보이도록 {input}을 추가해준다.


function Detail(){

  let [ alert, alert변경 ] = useState(true);
  let [input, setInput] = useState('');
  useEffect(()=>{
    let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
    console.log("안녕")
  });
  
  return (
    <HTML태그들/>

    { input }
    <input onChange={ (e)=>{ setInput(e.target.value) }}/>

    {
      alert === true
      ? (<div className="my-alert2">
          <p>재고가 얼마 남지 않았습니다</p>
        </div>)
      : null
    }
  )
}

컴포넌트가 계속 업데이트되도록 만들었고,
input에 무언가를 입력하면 콘솔창에 "안녕"이 계속 뜨며 useEffect도 계속 실행되는 것을 알 수 있다.


재렌더링할때는 useEffect 실행 방지하기

useEffect(()=>{
   let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
}, []);

useEffect() 함수 끝부분에 [ ] 를 넣을 수 있고, 이 안에는 state를 저장할 수 있다.

useEffect(()=>{
   let 타이머 = setTimeout(()=>{ alert변경(false) }, 2000);
}, [ alert ]);

위와 같이 alert를 넣어준다면 "alert라는 state가 변경될때만! useEffect를 실행해주세요" 가 된다.

즉 1.컴포넌트가 처음 로드될때 2.alert라는 state가 업데이트될때 만 실행된다.
또한 대괄호 [ ] 안에는 여러개의 state를 넣어줄 수 있다.

만약 대괄호 [ ] 안에 아무것도 넣지 않는다면
"컴포넌트가 처음 로드될때만 useEffect를 실행해주세요"
즉, 한 번만 실행하고 싶을때 사용하면 된다.


setTimeout 타이머를 해제하는 것도 필요!

2초 뒤 사라지는 코드가 실행되기전에 페이지를 벗어난다던가 하는 등의 상황이 올 경우 예기치 못한 오류가 발생할 수 있다.
그렇기 때문에
컴포넌트를 벗어날 경우 타이머를 해제하는 코드를 작성해주어야한다.

let 타이머 = useEffect(()=>{
	setTimeout(()=>{ setAlert(!alert) }, 2000);
   return ()=>{ clearTimeout(타이머) }
  }, []);

useEffect 안에 return을 추가한다면 return 뒤의 코드는 컴포넌트가 사라질때 실행된다.

그곳에 clearTimeout 을 추가해준다.

profile
안녕하세여

0개의 댓글