https://deahan.tistory.com/432
까지 아니 벌써 다 읽었다면,
12(12개월)는 소우주를 60(환갑)은 대우주를 경험한 것이니, 이제
당신의 손가락은 뇌의 간헐적 도움만으로도 화면을 지배할 느끼미를 가짐
보통 사이드효과라 불리는 useEffect 훅(Hook)을 훅하고 알아보자
재미가 쏠쏠하다.
Counter3.jsx
import { useEffect, useState } from "react";
import MyButton from "./MyButton";
function Counter3() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`안녕 경미니 ${count}`);
});
return (
<>
<h1>
경미니 <span style={{ color: "red" }}>{count}</span>번 호출
</h1>
<MyButton
style={{ color: "yellow" }}
onClick={() => {
setCount(count + 1);
}}
>
클릭
</MyButton>
</>
);
}
export default Counter3;
App.jsx
import Counter3 from "./Counter3";
function App() {
return (
<div>
<Counter3 />
</div>
);
}
export default App;
결과가 시선을 원한다.
클릭을 누를때 마다 useEffect 안 console.log가 실행됨을 알 수 있다.
이것은 무슨 의미? count 변수는 useState hook을 사용했기 때문에 reactive 변수다
곧 이 값이 바뀌면, Count3는 다시 그려지게 된(re-rendering).
다시 그려질 때 마다 실행되었단 의미가 의미 심장하다
Counter3.jsx 의 useEffect 부분만 아래 처럼 살짝 수정해보자
(눈에 거슬리는 밑줄이 생긴다면 ,일단 마구 무시해 버리자)
useEffect(() => {
console.log(`안녕 경미니 ${count}`);
}, []);
결과를 다시 확인하면, 버튼을 눌러도 console.log가 딱 1번 밖에 찍혀있음을 안다.
곧 처음에만 한번 실행되고, 다시 그려질 땐 실행되지 않는다.
다시 아래 처럼 추가 수정을 해보자.
useEffect(() => {
console.log(`안녕 경미니 ${count}`);
}, [count]);
결과를 다시 확인해 보면 버튼을 누를 때 마다 console.log가 다시 찍힘이 보인다.
, [ count ]); 부분을 디펜던시(dependecy)라 부르는데,
요 배열안에 있는 변수 값이 바뀔때마다 실행한다는 의미다.
Counter3.jsx 를 아래 처럼 수정해보자( count2 추가에 주목)
import { useEffect, useState } from "react";
import MyButton from "./MyButton";
function Counter3() {
const [count, setCount] = useState(0);
const [count2, setCount2] = useState(0);
useEffect(() => {
console.log(`안녕 경미니 ${count}`);
}, [count]);
return (
<>
<h1>
경미니{" "}
<span style={{ color: "red" }}>
{count} {count2}
</span>
번 호출
</h1>
<MyButton
style={{ color: "yellow" }}
onClick={() => {
setCount(count + 1);
}}
>
클릭
</MyButton>
<MyButton
style={{ color: "pink" }}
onClick={() => {
setCount2(count2 + 1);
}}
>
눌러유
</MyButton>
</>
);
}
export default Counter3;
결과를 확인하면, 클릭을 누르면 로그가 나오지만, 눌러유는 로그가 안나온다.
, [ count ]); 를 , [ count, count2]); 로 고쳐서도 한번 해보자. Good!
분명 뇌가 반짝였을것이다.
한개 더 맛을 보자. useEffect(...) 부분을 아래처럼 고친다
useEffect(() => {
console.log(`안농 경미니 ${count}`);
// 요건 언제 실행 되어용
return () => {
console.log(`미누가 좋으니 ${count}`);
};
}, [count]);
결과를 확인해 보기 바란다.
이제 정리를 해볼 시간이다
useEffect의 2번째 매개변수를 안 주면 그려질 때 마다 실행되고,
빈 배열 []을 주면, 처음 그려질 때(rendering) 1번만 실행되고,
배열안에 값을 주면 해당 값에 변화가 생길때만 실행된다.
useEffect 안에서 return 되는 함수의 로그도 보았을 것이다.(이것은 뭐지?)
조금 더 정확히 이야기 하면 영어로는 mount / unmount 라는 표현을 쓰는데,장착 / 제거 라는
의미로 컴퓨터에 하드디스크등을 다는 것을 mount라 하고 빼는 것을 unmount라고 하였다.
이 표현을 빌려서 HTML 문서에 곧 document 객체에 DOM Element를
추가하는 것을 mount, 제거하는 것을 unmount라고 하는데.
mount 될 때(append, appendChild...) 실행되는 것이 useEffect(..) 안의 코드고,
unmount(remove, removeChild...) 될 때 return 된 함수가 실행된다.
말이 어렵다?, 괜찮다! 시간은 항상 젊디 젊은 당신(아직 환갑 머나 멈) 편이다.
(페이스북 개발자들도 평균 3개월을 소비했다니..)
Counter3.jsx 를 아래 처럼 수선한 뒤 결과 확인
import { useEffect, useState } from "react";
import MyButton from "./MyButton";
function Counter3() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`안농 경미니 ${count}`);
// 요건 언제 실행 되어용
return () => {
console.log(`미누가 좋으니 ${count}`);
};
}, [count]);
return (
<>
<h1>
경미니{" "}
<span style={{ color: "red" }}>{count}</span>
번 호출
</h1>
<MyButton
style={{ color: "yellow" }}
onClick={() => {
setCount(count + 1);
}}
>
클릭
</MyButton>
<MyButton
style={{ color: "pink" }}
onClick={() => {
setCount(0);
}}
>
0으로 초기화
</MyButton>
</>
);
}
export default Counter3;
useEffect를 어디에 쓰면 좋을지 꼭 한번 고민해 보기 바람. (???)
React 코딩 스타일에 익숙해지기 위해서 한 걸음만 더 나가보자.
아래 명령어로 faker(더미 데이터 생산용) 모듈을 개발용 Dependency로 설치 하자
npm install -D @faker-js/faker
덩말로 궁금하다면 아래 링크 방문하면 된다...
https://www.npmjs.com/package/@faker-js/faker
Counter3.jsx 를 아래와 같이 새로 작성.(길지만 이미 거의 아는 내용)
import { useEffect, useRef, useState } from "react";
import MyButton from "./MyButton";
import { faker } from "@faker-js/faker/locale/ko";
// 바꾸지 않을 값이라면 function밖에 또는(선택) 안에 써도 된당.
const bestFriens = [
{ fid: "f001", name: "경미닝", age: 24, avatar: "energy" },
{ fid: "f002", name: "미누니", age: 42, avatar: "like" },
{ fid: "f003", name: "선주니", age: 29, avatar: "search" },
{ fid: "f004", name: "병처니", age: 27, avatar: "alcohol" },
];
// faker-js 이용
const person = faker.person;
function Counter3() {
let fid = useRef(1);
const [myFriend, setMyFriend] = useState(bestFriens);
useEffect(() => {
//console.log(`안농 경미니`);
return () => {
//console.log(`미누가 좋으니`);
};
}, [myFriend]);
const addFriend = () => {
const pName = person.firstName();
const friend = {
fid: `new${fid.current++}`,
name: pName,
age: Math.floor(Math.random() * 40) + 20,
avatar: pName,
};
console.log("체크:", friend);
const friends = [friend, ...myFriend];
setMyFriend(friends);
};
return (
<>
<MyButton onClick={addFriend}>친구 추가</MyButton>
<MyButton
onClick={() => {
setMyFriend([]);
}}
>
친구 클리어
</MyButton>
{myFriend.length != 0 ? (
myFriend
.filter((friend) => friend.age < 40)
.map((friend) => (
<div key={friend.fid}>
<span style={{ fontWeight: "bold" }}>{friend.name}</span>
<img
src={`${avatarURL}${friend.name}`}
width={200}
height={200}
/>
</div>
))
) : (
<h1>금수저 친구 떠남</h1>
)}
</>
);
}
export default Counter3;
결과에 시선이 별로 끌리지만 눌러본다.
filter(나이 40이하)로 미누를 골라낸 다음 3명을 화면에 그린다.
눈에 쌍심지를 꼬치처럼 세우고 봐야 할 부분은 아래다.
const friends = [friend, ...myFriend];
// myFriend.push(friend) // 윗 줄을 주석처리 하고 이렇게 쓴다면...?? 반드시 해보길
setMyFriend(friends);
위 ... 전개 연산자(Spread Operator)가 이해가 안된다면
2023.06.14 - [자바스크립트] - 시베리안 허숙희의 자바스크립트 비기닝 18 (구조 분해 등등..)
필히 필사적으로 글을 딱딱 씹어서 읽고 먹고 와야 한다.
꽤 중요한 부분인뎅..... 주석된 부분을 열고, 그 윗줄을 주석 처리하면
코드가 제대로 동작하지 않는다. React는 같은 객체[여기선 배열]가 오면 변화가 없다고 판단한다.
새로운 객체를 할당해 주어야 한다. 중요하다면 그렇다면 기억하자.
이렇게 하는 이유는 메모리는 조금더 소비되겠지만, 객체 변화 history추적이 용이하다.
e7e샘은 정말 천재인가..
출처 : https://e-7-e.tistory.com/261