일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- JS 기초
- JS 타이머기능
- JS prompt
- git 협업셋팅
- js 변수
- JS null undefined
- JS setInterval
- JS typeof연산자
- JS appendChild
- JS preventDefault
- JS form
- HTML기초
- JS 데이터타입
- JS clearInterval
- JS classList
- JS redirection
- JS append
- JS localStorage
- JS 숫자
- JS setTimeout
- JS 스코프
- CSS기초
- JS 함수
- JS 연산
- JS 삼항연산
- JS 형변환
- CSS속성정리
- JS value속성
- JS 화살표함수
- JS form action
공부기록용
ReactJS로 영화 웹 서비스 만들기(06/useEffect, cleanup ) 본문
https://nomadcoders.co/react-for-beginners/lobby
특정 코드의 실행을 제한하고 싶을때 useEffect를 사용하자.
import { useState } from "react";
function App() {
const [counter, setCounter] = useState(0);
function onBtnClick() {
return setCounter((prev)=>{
return prev +1
})
}
console.log('i run all the time')
return (
<div>
<h1>{counter}</h1>
<button onClick={onBtnClick}>Click me!</button>
</div>
);
}
export default App;
> 버튼을 클릭해서 counter이 변하므로 렌더링이 발생하는 것은 맞지만 console.log('i run all the time')은 범위에 해당하지 않으므로 굳이 렌더링되지 않아도 되는 부분이다. 근데 계속해서 버튼을 누르면 같이 렌더링 되는 것을 볼 수 있다. 이때 불필요한 렌더링을 막기 위해서 useEffect( )를 사용한다.
useEffect( )
// useEffect의 두번째 인자가 의존성 배열이 들어가는 곳 useEffect(()=>{ // 실행하고 싶은 함수 }, [의존성배열])
import { useState, useEffect } from "react";
function App() {
const [counter, setCounter] = useState(0);
function onBtnClick() {
return setCounter((prev)=>{
return prev +1
})
}
console.log('i run all the time')
const once=()=>{
console.log('i run only once')
}
useEffect(once, [])
return (
<div>
<h1>{counter}</h1>
<button onClick={onBtnClick}>Click me!</button>
</div>
);
}
export default App;
> counter이 버튼의 클릭으로 값이 바뀌면 전체의 코드가 다시 또 리렌더링이 되어야 하지만 useEffect를 통해서
console.log('i run only once')를 막아주어서 해당 내용은 최초 페이지의 렌더링 시에만 'i run only once'를 볼 수 있게 되었다.
이렇게 바꿔줄 수 있다. 즉, useEffect는 지정한 코드가 한 번만 실행될 수 있도록 보호해주는 것이다.
(의존성 배열에 빈배열[ ]을 넣어줌으로써)
useEffect(() => {
console.log('i run only once')
}, [])
input창에 값을 입력할 수 있게 하고, 그 값은 변하니까 state시키고
import { useState, useEffect } from "react";
function App() {
const [counter, setCounter] = useState(0);
const [keyword, setKeyword] = useState('');
function onBtnClick() {
return setCounter((prev)=>{
return prev +1
})
}
console.log('i run all the time')
const onChangekeyword = (event) => {
setKeyword(event.target.value)
}
useEffect(() => {
console.log('i run only once')
}, [])
return (
<div>
<input
value={keyword}
onChange={onChangekeyword}
type="text"
placeholder="Search here..." />
<h1>{counter}</h1>
<button onClick={onBtnClick}>Click me!</button>
</div>
);
}
export default App;
const [keyword, setKeyword] = useState('');
> 입력 내용을 keyword로 받고 그게 업데이트setKeyword된다
<input
value={keyword}
onChange={onChangekeyword}
type="text"
placeholder="Search here..." />
> input창에 입력 내용은 keyword인거고 바뀔때마다_onChange 이벤트 발생
const onChangekeyword = (event) => {
setKeyword(event.target.value)
}
> onChangekeyword() 함수를 실행할꺼다
> onChangekeyword() 함수는 value를 뽑아와서 setKeyword가 되고 그 setKeyword는 결국의 최종 keyword이다.
그래서
> input에 onChange 이벤트가 발생하면 onChangeKeyword함수가 실행되서 value를 뽑아와 setKeyword로 넘겨서 결국 keyword가 되게 되는 것으로 값이 변하는 형태로써 렌더링이 발생하게 된다.
> 전체 코드의 실행으로 console.log('i run all the time')역시 렌더링되어 콘솔에 찍히는 것이고 이때, useEffect를 지정해 놓은 console.log('i run only once')를 제외하고 모든 코드가 실행되는 것이다.
import { useState, useEffect } from "react";
function App() {
const [counter, setCounter] = useState(0);
const [keyword, setKeyword] = useState('');
function onBtnClick() {
return setCounter((prev)=>{
return prev +1
})
}
console.log('i run all the time')
const onChangeKeyword = (event) => {
setKeyword(event.target.value)
}
useEffect(() => {
console.log('i run only once')
}, [])
console.log("SEARCH FOR", keyword)
return (
<div>
<input
value={keyword}
onChange={onChangeKeyword}
type="text"
placeholder="Search here..." />
<h1>{counter}</h1>
<button onClick={onBtnClick}>Click me!</button>
</div>
);
}
export default App;
function onBtnClick() {
return setCounter((prev)=>{
return prev +1
})
}
console.log('i run all the time')
const onChangeKeyword = (event) => {
setKeyword(event.target.value)
}
useEffect(() => {
console.log('i run only once')
}, [])
console.log("SEARCH FOR", keyword)
> input에 값이 생기거나 click 이벤트가 발생되면
> console.log('i run only once')는 useEffect걸어두어서 콘솔에 출력X
> console.log('i run all the time')와 console.log("SEARCH FOR", keyword)는 이벤트가 일어날 때마다 실행된다. 즉, 렌더링되어서 나타나 지는것이다.
한번 더 체크 input에 값이 생기면 console.log("SEARCH FOR", keyword), 버튼이 클릭되면 console.log('i run only once') 만 렌더링 되게끔 하고 싶은 것
counter변화가 아닌 keyword의 변화시에만 console.log("SEARCH FOR", keyword)이 렌더링 되도록 하고 싶다.
useEffect(() => {
console.log("SEARCH FOR", keyword)
}, [keyword])
> 의존성배열 자리에 [ ] -> 안에 들어가는 내용은 해당 내용이 변화할때마다 코드를 실행하겠다는 것으로 현재는 keyword가 변할때만 console.log("SEARCH FOR", keyword)를 실행하겠다는 의미이다.
> useEffect로 [keyword]넣어주니까 keyword가 변할때만 렌더링되고 그 외인 버튼 클릭시에는 console.log("SEARCH FOR", keyword)의 렌더링은 일어나지 않게 되었다.
추가로 keyword에 조건을 걸어주자
useEffect(() => {
if(keyword !== "" && keyword.length > 5){
console.log("SEARCH FOR", keyword)
}
}, [keyword])
> keyword가 변화해서 해당 useEffect를 실행하는데
>> 만약 keyword가 빈 값이 아니고 5글자 이상일 경우("SEARCH FOR", keyword)를 출력해주겠다.
import { useState, useEffect } from "react";
function App() {
const [counter, setCounter] = useState(0);
const [keyword, setKeyword] = useState('');
// 버튼클릭시
function onBtnClick() {
return setCounter((prev)=>{
return prev +1
})
}
// input 값 입력, 변화시
const onChangeKeyword = (event) => {
setKeyword(event.target.value)
}
// 맨 처음 렌더링 시
useEffect(() => {
console.log('i run only once')
}, [])
// counter변화시 -> 버튼 클릭시
useEffect(() => {
console.log("i run when 'counter' changes.")
}, [counter])
// keyword변화시
useEffect(() => {
console.log("i run when 'keyword' changes.")
}, [keyword])
// counter와 keyword 중 하나라도 변하면 발생
useEffect(() => {
console.log("i run when 'keyword' & 'counter' changes.")
}, [counter, keyword])
return (
<div>
<input
value={keyword}
onChange={onChangeKeyword}
type="text"
placeholder="Search here..." />
<h1>{counter}</h1>
<button onClick={onBtnClick}>Click me!</button>
</div>
);
}
export default App;
기본적으로 React는 새로운 데이터가 들어올 때 마다 UI를 렌더링한다 그래서 불필요한 소모가 많아지고 비효율적이다. 그래서 변화하지 않는 부분에 대해서 같이 렌더링되는 것을 막기 위해서 useEffect를 사용해서 조건을 걸어준다고 생각하면 된다. ([ ]에 들어간 부분의 값이 변한다면 조건을 실행하겠다.)
복습
import { useState } from "react";
function App() {
const [showing, setShowing] = useState(false);
function onClick(){
setShowing(prev => !prev)
}
return <div>
<button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
</div>;
}
export default App;
import { useEffect, useState } from "react";
function Hello(){
useEffect(()=>{
console.log("i'm here")
}, [])
return <h1>Hello</h1>
}
function App() {
const [showing, setShowing] = useState(false);
function onClick(){
setShowing(prev => !prev)
}
return <div>
<button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
{showing ? <Hello /> : null}
</div>;
}
export default App;
return <div>
<button onClick={onClick}>{showing ? "Hide" : "Show"}</button>
{showing ? <Hello /> : null}
</div>;
> 초기 값이 false이니까 첫 렌더링 시 show가 보여지는 것
function onClick(){
setShowing(prev => !prev)
}
> 버튼을 클릭하면 onClick함수 작동으로 값이 반대로 ! 바뀌면서 setShowing -> showing으로 바뀐 값이 다시 셋팅
> 그럼 true가 되고
return <div>
<button onClick={onClick}>{showing ? "Hied" : "Show"}</button>
{showing ? <Hello /> : null}
</div>;
> Hide로 바뀌면서
{showing ? <Hello /> : null}
function Hello(){
useEffect(()=>{
console.log("i'm here")
}, [])
return <h1>Hello</h1>
}
> showing의 true로 <Hello />실행 되니까 콘솔에 i'm here와 페이지에<h1>Hello</h1> 출력됨
cleanup 함수
컴포넌트가 destroy될 때도 코드를 실행할 수 있다.
-> return으로 함수를 만들어주면 된다. useEffect는 함수를 받고, 이 함수는 dependency가 변화할 때 호출됨
현재는 dependency가 비어있으니 컴포넌트가 처음 생성될 때 함수가 호출된 후 다시 호출 되지 않음 그래서 컴포넌트가 파괴될 때도 함수를 실행하고 싶으면 useEffect 함수가 새로운 함수를 return해야 함
-> 왜냐면 deps가 비어있으면 자동으로 컴포넌트가 파괴될 때 cleanup함수가 실행되는데 그 과정이 리렌더링으로 useEffect함수가 실행되고 클린업하면서 이전에 있던 이펙트인 console.log(“created :) )가 삭제되고 새로운 이펙트 함수인 return함수가 실행되기 때문이다.
리렌더링 -> 이전 이펙트 클린업 -> 이펙트 실행
function Hello(){
useEffect(()=>{
console.log("created :>");
return function(){
console.log("destoryed :<")
}
}, [])
return <h1>Hello</h1>
}
해당 실행 함수가 언제 발생되고 사라지는지 알 수 있다.
useEffect(function(){
실행하고 싶은 함수(A.변경된 값이 화면에 나타날 때)
return function(){
변경된 값이 화면에서 사라질 때 실행할 함수
}
}, [이 값이 변경되면])
같은 결과1
function Hello(){
// 함수가 사라질 때
function destoryedFnc(){
console.log("destoryed :<")
}
// 함수가 실행시
function createdFnc(){
console.log("created :>");
return destoryedFnc;
}
useEffect(createdFnc, []);
return <h1>Hello</h1>
}
> Hello는 [ ]가 바뀔때 실행_비어있는 관계로 처음 component가 생성될 때만(페이지의 첫 렌더링) Hello함수가 호출
같은 결과2
function Hello() {
useEffect(() => {
console.log("hi :)");
return () => {
console.log('bye:(')
}
}, []);
return <h1>Hello</h1>;
}
//////////////////////////////
function Hello() {
useEffect(function () {
console.log("hi :)");
return function(){
console.log("bye :(");
}
}, []);
return <h1>Hello</h1>;
}
'📚강의록📚 > 노마드)React' 카테고리의 다른 글
ReactJS로 영화 웹 서비스 만들기(07_2/Movie App01_fetch로 데이터 불러오기 및 component) (0) | 2023.07.19 |
---|---|
ReactJS로 영화 웹 서비스 만들기(07_1/Todo만들기) (0) | 2023.07.19 |
ReactJS로 영화 웹 서비스 만들기(04_3/prop type) (0) | 2023.07.13 |
ReactJS로 영화 웹 서비스 만들기(04_2/props활용, React.memo) (0) | 2023.07.13 |
ReactJS로 영화 웹 서비스 만들기(04_1/props이해하기, props추출) (0) | 2023.07.13 |