state 변할 때마다 뭔가 다른 효과를 주고 싶은 경우
state가 변경되어 렌더링 될 때 실행하는 부분
useEffect(() => {
// state가 변경되어 렌더링 될 때 실행하는 부분
return () => {
// 다시 렌더링하기 이전에 실행되는 부분
}
}, [state 값이 들어간다.])
// 컴포넌트가 업데이트 될 때마다 매번 실행
useEffect(() => {
console.log('hi');
})
// 처음만 실행
useEffect(() => {
console.log('hi');
}, [])
// 변수들의 변화가 일어날 때마다 실행
useEffect(() => {
console.log('hi');
}, [변수1, 변수2])
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>
)
}
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초마다 반복해주는 동작 삭제해주기
refContainer.current
const refContainer = useRef(initialValue);
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;
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;