22-11-17-리액트(6)

YJ·2022년 11월 18일
0
post-thumbnail

Hook - useEffect

state 변할 때마다 뭔가 다른 효과를 주고 싶은 경우
state가 변경되어 렌더링 될 때 실행하는 부분

  • useEffect 기본 형태
useEffect(() => {
  	// state가 변경되어 렌더링 될 때 실행하는 부분
	return () => {
    	// 다시 렌더링하기 이전에 실행되는 부분
    }
}, [state 값이 들어간다.])
  • useEffect 형태
// 컴포넌트가 업데이트 될 때마다 매번 실행
useEffect(() => {
	console.log('hi');
})

// 처음만 실행
useEffect(() => {
	console.log('hi');
}, [])
// 변수들의 변화가 일어날 때마다 실행
useEffect(() => {
	console.log('hi');
}, [변수1, 변수2])

useEffect 활용 코드

import {useState, useEffect} from 'react'

function Counter() {
	const [count, setCount] = useState(0);
  // button 클릭하면 count + 1
  	const handleCountUp = (e) => {
    	setCount = (count + 1)
    }
    // count 변수를 관찰하여 변할때마다 실행시켜주기
    useEffect(() => {
    	if (count % 2) {
        	alert('홀수');
        } else {
        	alert('짝수');
        }
    }, [count])
  
    return (
    	<>
      		<div>{count}</div>
      		<button onClick={handleCountUp}>click!</button>
      	</>
    )
}

function App () {
	return (
    	<div>
      		<Counter/>
      	</div>
    )
}

useEffect는 state를 지정하여 해당 state가 변경됨을 감지한다면 함수를 실행시킨다.

페이지 새로고침하여 클릭하지 않았는데도 alert 창이 나오는 경우?
-> useState(0)에서 0으로 count 값을 초기화하면서 count 값이 변하기 때문에 실행된다.

  • 새로고침할때 실행되지 않도록 변경
import {useState, useEffect} from 'react'

function Counter() {
	const [count, setCount] = useState(0);
  	const [checkRender, setCheckRender] = useState(false);
  // button 클릭하면 count + 1
  	const handleCountUp = (e) => {
    	setCount = (count + 1)
    }
    // count 변수를 관찰하여 변할때마다 실행시켜주기
    useEffect(() => {
      // 처음은 false로 실행해서 alert창 띄우지 않기
      if (checkRender) {
    	if (count % 2) {
        	alert('홀수');
        } else {
        	alert('짝수');
        }
      }
      setCheckRender(true);
    }, [count])
  
    return (
    	<>
      		<div>{count}</div>
      		<button onClick={handleCountUp}>click!</button>
      	</>
    )
}

function App () {
	return (
    	<div>
      		<Counter/>
      	</div>
    )
}
  • Date 객체를 활용하여 새로고침 없이 실시간 반영
import React, { useState, useEffect } from 'react';

function Time(props) {
  const [today, setToday] = useState(new Date());
  const [hour, setHour] = useState(today.getHours());
  const [min, setMin] = useState(today.getMinutes());
  const [sec, setSec] = useState(today.getSeconds());
  console.log("렌더링이 됩니다..?")//렌더링이 잘 되는지 확인용

  // 성능이슈가 발생되는 공간
  useEffect(() => {
  	let time = setInterval(() => {
     const t = new Date();
     setToday(t);
     setHour(t.getHours());
     setMin(t.getMinutes());
     setSec(t.getSeconds());
  }, 1000);
    return () => {
      	// 각각 34초 35초 36초가 setInterval()을 실행하므로
      	// 컴포넌트 사라지기 전 setInterval을 clearInterval 해주기
    	clearInterval(time);
    }
  }, [today]);
  

  return (
    <div>
      <h1>
        시간 : {hour}{min}{sec}</h1>
    </div>
  );
}

function App() {
  return (
    <div>
      <Time/>
    </div>
  );
}

export default App;

setInterval -> 1초에 한번씩 같은 동작 반복
-> setState 횟수가 계속 추가
-> 1초마다 반복해주는 동작 삭제해주기

Hook - useRef

  • 값의 접근 refContainer.current
const refContainer = useRef(initialValue);
  1. 렌더링이 되어도 값이 변하는거에 상관없이 값을 변경하고 싶은 경우 useRef 사용
    • useRef는 렌더링되어도 값이 변경되지 않는다.
  2. 컴포넌트 태그에 직접 접근하고 싶은 경우에 useRef 사용
    DOM - querySelector, getElementById 사용
    React - useRef 사용

ref - 전역으로 작동하지 않고 컴포넌트 내부에서만 작동 (id 대신 ref 사용)

import React, {useState, useEffect, useRef} from 'react';

function Counter () {
	const [count, setCount] = useState(0);
  	const [countTwo, setCountTwo] = useState(0);
  	// ref는 렌더링되어도 값 유지
  	let countThree = useRef(0);
  	// 일반변수 렌더링되면 초기화
  	let countFour = 0;
  
  	const handleCountUp = (e) => {
	setCount(count + 1);
    }
    const handleCountUpTwo = (e) => {
        setCount(countTwo + 1);
    }
    // 변수의 값은 증가하지만 렌더링되지는 않는다.
    const handleCountUpThree = (e) => {
        countThree.current = countThree.current + 1;
    }
    // 렌더링은 안되고 재렌더링 되어도 0으로 초기화
    const handleCountUpFour = (e) => {
        countFour = countFour + 1;
    }

    useEffect(() => {
        console.log('count가 감시되고 있습니다.')
        console.log(`감시된 변수 : ${count}`)
    },[count]);
  	return (
      <>
        <div>{count}</div>
        <button onClick={handleCountUp}>up!</button>
        <div>{countTwo}</div>
        <button onClick={handleCountUpTwo}>up!</button>
        <div>{countThree.current}</div>
        <button onClick={handleCountUpThree}>up!</button>
        <div>{countFour}</div>
        <button onClick={handleCountUpFour}>up!</button>
      </>
    )
  
}

function App () {
  return (
    <div>
      <Counter/>
    </div>
  );
}
export default App;
  • input창 입력한 후 버튼 누르면 입력 내용 보여주기
    button 이벤트 발생하면 값을 받아와서 상태값 변경시켜주기
import React, {useState, useRef} from 'react';

const App = () => {
  // useRef를 활용하여 input 요소에 접근 가능
  	const emailInput = useRef(null);
  	const pwInput = useRef(null);
  
  // state 값
	const [emailValue, setEmailValue] = useState('');
	const [pwValue, setPwValue] = useState('');
  
  	const inputChect = (e) => {
    	e.preventDefault();
      // 상태 값 변경
      	setEmailValue(emailInput.current.value);
      	setPwValue(pwInput.current.value);
    }
  
  	reutn (
      <form style={{ display: "flex", flexDirection: "column" }}>
        <label>
          이메일 : <input type="email" ref={emailInput} />
            // ref로 props 전달
        </label>
        <label>
          비밀번호 : <input type="password" ref={pwInput} />
        </label>
        <button type="submit" style={{ width: "100px" }} onClick={inputCheck}>
          회원가입
        </button>
        <span>{emailValue}</span>
        <span>{pwValue}</span>
      </form>
    );
}
export default App;
profile
함께 배워나가고 싶습니다!

0개의 댓글