강의 링크 :
https://www.youtube.com/watch?v=U7zNZrLhhlA&list=PL93mKxaRDidEfLM0I_FFb-98vfAQgXT82&index=4
https://www.youtube.com/watch?v=IQovah5bz3Q&list=PL93mKxaRDidEfLM0I_FFb-98vfAQgXT82&index=5
해당 게시글은 위 링크의 강의를 보고 해당 내용을 정리한 게시글입니다!
지금까지 배운 내용을 토대로라면

밑줄 친 부분만 변경하고자 했을 때, 결국 이 return이 다시 실행되기 때문에
이 리턴되는 영역 자체가 다시 실행된다(그려진다)는 것이다.
함수가 하나로 묶여 있기 때문에 다른 부분만을 따로 렌더링 할 수 없다는 것이다.

이 도토리만 사과로 바꾸기 위해선 어떻게 해야할까?

정답은 이렇게 컴포넌트화 시키는 것이다.
따로 모듈로 분리시키는 것이다.
이렇게 컴포넌트화 시킬 경우 도토리에도 return이 있을 거고, 아래 다람쥐에도 return이 있을 것이다.
각각 따로 렌더링 할 수 있다는 장점이 있다.
저기서 도토리를 A , 다람쥐를 B 라고 하자
리액트 엔진은 A 부모가 다시 그려지면 자식(여기서 B)도 다시 그려야 할지 연산한다.
연산을 해서 다시 그려야하면 다시 그리고, 안 그려도 되면 안 그리게 된다.
자식을 다시 그려야한다면 B는 A에 의존적이다. (의존성이 있다.)
B가 A가 의존적이지 않다는 것은 상태 데이터를 공유하고 있지 않다는 것이다.
만약 저 B컴포넌트에 다람쥐를 피카츄로 바꾼다고 해보자
데이터가 수천개가 있는데 그 중에 하나에 다람쥐가 있다고 생각해보자
이 연산을 최적화시키는 것이 중요하다는 생각이 들 것이다.
그럼 이 연산을 어떻게 최적화할 수 있을까?
정답은 깊은 복사이다.
깊은 복사를 하게 되면 레퍼런스만 비교해서
어떤 부분이 달라졌는지 감지해 다시 그려야할지 아닐지 확인할 수 있다.
따라서 실제 배열을 컨트롤 할 수 있는 함수가 JS에 많이 있지만
여기선 깊은 복사 해주는 함수인 불변함수를 공부할 것이다.
우선, HTML 파일을 브라우저로 바로 열어 확인할 수 있게 확장 프로그램을 설치하자


이는 레퍼런스(주소)를 저장하는 얕은 복사이다.
깊은 복사를 가장 쉽게 하는 방법은 스프레드 연산자를 이용하는 것이다.
스프레드 연산자

실행결과 )

깊은 복사를 하였으므로 a의 데이터가 변경되지 않았다.
추가하기

실행결과 )

걸러내기

실행결과 )

잘라내기 (삽입)

실행결과 )

반복하기

map((n) => { return n })은 줄여서 map((n) => n) 으로 할 수 있다.
const b5 = [...a5] 스프레드와 동일한 결과지만 이렇게 반복하기를 통한 이점은
값을 가공할 수 있다는 것이다.
실행결과 )

+ 오브젝트를 통한 연산

데이터는 변경되지만 주소가 변경되지 않으므로 최적화가 되지 않는다.
따라서 이렇게 작성하면 안된다.
그러면 어떻게 작성해야 할까?
일단 이것을 알고 있어야 한다.
const a6 = { id: 1, name: '구이름' };
const b6 = { ...a6, name: '신이름' };
console.log(b6);
뒤에 나온 데이터가 덮어써준다. 따라서 이렇게 작성하면
이전 데이터들은 그대로고 '구이름'만 '신이름'으로 변경된다.
const data = { phone: '2222' };
const a6 = {
id: 1,
name: '도토리',
phone: '1111',
age: 20,
gender: '남',
};
const b6 = { ...a6, ...data };
console.log(b6);
마찬가지이다.
뒤에 나온 데이터가 덮어쓴다. 폰 '2222'가 '1111'로 되는 것이다.
여기서 id :2를 찾아서 phone을 7979로 어떻게 바꿀 수 있을까?
filter로 찾아야할까 map으로 찾아야할까?
기존 데이터들은 그대로 유지하고 id:2의 phone만 7979로 변경해야 한다.
filter를 사용하면 id:2 빼고는 데이터가 날아가기 때문에 map을 사용해야 한다.
map을 사용하고 id:2 만 스프레드 연산자로 덮어씌워주면 된다.

실행결과 )

test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
</head>
<body>
<script>
// 깊은 복사를 할 수 있는 함수
// concat, filter, map, slice, 스프레드(전개) 연산자
console.log('1. ------------- 스프레드 연산자 ------------- ');
const a = [1, 2, 3];
const b = [...a]; // 스프레드 연산자
b.push(4); // b의 데이터를 변경하였다. 깊은 복사라면 a의 데이터가 달라져서는 안된다.
console.log(`a의 값은 : ${a}`); // 1,2,3
console.log(`b의 값은 : ${b}`); // 1,2,3,4
console.log('2. ------------- 추가하기 ------------- ');
const a2 = [1, 2, 3];
const b2 = a2.concat(4);
console.log(`a2의 값은 : ${a2}`); // 1,2,3
console.log(`b2의 값은 : ${b2}`); // 1,2,3,4
// a2.push(4); 의 결과는 4
const c2 = [...a, 4];
const d2 = [0, ...a, 4];
console.log(`c2의 값은 : ${c2}`); // 1,2,3,4
console.log(`d2의 값은 : ${d2}`); // 0,1,2,3,4
console.log('3. ------------- 걸러내기 ------------- '); // 삭제할 때 사용한다.
const a3 = [1, 2, 3];
const b3 = a3.filter((n) => {
return n != 1;
}); // boolean을 리턴받는다. true만 가져온다.
console.log(`a3의 값은 : ${a3}`); // 1,2,3
console.log(`b3의 값은 : ${b3}`); // 2,3
console.log('4. ------------- 잘라내기(삽입) ------------- ');
const a4 = [1, 2, 3];
const b4 = a4.slice(0, 2); // 마지막 인덱스는 직전까지다 포함X
console.log(a4); // [1,2,3]
console.log(b4); // [1,2]
const c4 = [a4.slice(0, 2)];
console.log(c4); // [[1,2]]
const d4 = [...a4.slice(0, 2), 4, ...a4.slice(2, 3)];
console.log(d4); // [1,2,4,3]
console.log('5. ------------- 반복하기 ------------- ');
const a5 = [1, 2, 3];
// for(let i=0; i<a5.length; i++) console.log(a5[i]);
// const c5 = a5.forEach((n) => { console.log(n); }); 이렇게 해봤자 c5는 null이다. (리턴 안되므로)
const b5 = a5.map((n) => {
return n;
});
// const b5 = [...a5]; 와 동일한 결과
// 깊은 복사이므로 b5와 a5는 다른 레퍼런스이다.
console.log(b5);
</script>
</body>
</html>
이렇게 작성한 코드를 이제 적용시켜 보자
App.js
import './App.css';
function App() {
let list = [1, 2, 3];
return (
<div>
<div>
{list.map((n) => (
<h1>{n}</h1>
))}
</div>
</div>
);
}
export default App;
forEach는 리턴이 안되므로 map으로 작성해야 화면에 표시된다.
태그 사이의 n을 변수취급 하기 위해 {}로 작성한다.
실행결과 )

'자바 스프링 > react & springboot' 카테고리의 다른 글
#4 React useEffect, useMemo, useRef (0) | 2023.02.12 |
---|---|
#3 React useState (0) | 2023.02.11 |
#1 React 실행흐름, 기본문법 (0) | 2023.01.19 |
#0 React 설치 및 세팅 (0) | 2023.01.18 |
강의 링크 :
https://www.youtube.com/watch?v=U7zNZrLhhlA&list=PL93mKxaRDidEfLM0I_FFb-98vfAQgXT82&index=4
https://www.youtube.com/watch?v=IQovah5bz3Q&list=PL93mKxaRDidEfLM0I_FFb-98vfAQgXT82&index=5
해당 게시글은 위 링크의 강의를 보고 해당 내용을 정리한 게시글입니다!
지금까지 배운 내용을 토대로라면

밑줄 친 부분만 변경하고자 했을 때, 결국 이 return이 다시 실행되기 때문에
이 리턴되는 영역 자체가 다시 실행된다(그려진다)는 것이다.
함수가 하나로 묶여 있기 때문에 다른 부분만을 따로 렌더링 할 수 없다는 것이다.

이 도토리만 사과로 바꾸기 위해선 어떻게 해야할까?

정답은 이렇게 컴포넌트화 시키는 것이다.
따로 모듈로 분리시키는 것이다.
이렇게 컴포넌트화 시킬 경우 도토리에도 return이 있을 거고, 아래 다람쥐에도 return이 있을 것이다.
각각 따로 렌더링 할 수 있다는 장점이 있다.
저기서 도토리를 A , 다람쥐를 B 라고 하자
리액트 엔진은 A 부모가 다시 그려지면 자식(여기서 B)도 다시 그려야 할지 연산한다.
연산을 해서 다시 그려야하면 다시 그리고, 안 그려도 되면 안 그리게 된다.
자식을 다시 그려야한다면 B는 A에 의존적이다. (의존성이 있다.)
B가 A가 의존적이지 않다는 것은 상태 데이터를 공유하고 있지 않다는 것이다.
만약 저 B컴포넌트에 다람쥐를 피카츄로 바꾼다고 해보자
데이터가 수천개가 있는데 그 중에 하나에 다람쥐가 있다고 생각해보자
이 연산을 최적화시키는 것이 중요하다는 생각이 들 것이다.
그럼 이 연산을 어떻게 최적화할 수 있을까?
정답은 깊은 복사이다.
깊은 복사를 하게 되면 레퍼런스만 비교해서
어떤 부분이 달라졌는지 감지해 다시 그려야할지 아닐지 확인할 수 있다.
따라서 실제 배열을 컨트롤 할 수 있는 함수가 JS에 많이 있지만
여기선 깊은 복사 해주는 함수인 불변함수를 공부할 것이다.
우선, HTML 파일을 브라우저로 바로 열어 확인할 수 있게 확장 프로그램을 설치하자


이는 레퍼런스(주소)를 저장하는 얕은 복사이다.
깊은 복사를 가장 쉽게 하는 방법은 스프레드 연산자를 이용하는 것이다.
스프레드 연산자

실행결과 )

깊은 복사를 하였으므로 a의 데이터가 변경되지 않았다.
추가하기

실행결과 )

걸러내기

실행결과 )

잘라내기 (삽입)

실행결과 )

반복하기

map((n) => { return n })은 줄여서 map((n) => n) 으로 할 수 있다.
const b5 = [...a5] 스프레드와 동일한 결과지만 이렇게 반복하기를 통한 이점은
값을 가공할 수 있다는 것이다.
실행결과 )

+ 오브젝트를 통한 연산

데이터는 변경되지만 주소가 변경되지 않으므로 최적화가 되지 않는다.
따라서 이렇게 작성하면 안된다.
그러면 어떻게 작성해야 할까?
일단 이것을 알고 있어야 한다.
const a6 = { id: 1, name: '구이름' };
const b6 = { ...a6, name: '신이름' };
console.log(b6);
뒤에 나온 데이터가 덮어써준다. 따라서 이렇게 작성하면
이전 데이터들은 그대로고 '구이름'만 '신이름'으로 변경된다.
const data = { phone: '2222' };
const a6 = {
id: 1,
name: '도토리',
phone: '1111',
age: 20,
gender: '남',
};
const b6 = { ...a6, ...data };
console.log(b6);
마찬가지이다.
뒤에 나온 데이터가 덮어쓴다. 폰 '2222'가 '1111'로 되는 것이다.
여기서 id :2를 찾아서 phone을 7979로 어떻게 바꿀 수 있을까?
filter로 찾아야할까 map으로 찾아야할까?
기존 데이터들은 그대로 유지하고 id:2의 phone만 7979로 변경해야 한다.
filter를 사용하면 id:2 빼고는 데이터가 날아가기 때문에 map을 사용해야 한다.
map을 사용하고 id:2 만 스프레드 연산자로 덮어씌워주면 된다.

실행결과 )

test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>React App</title>
</head>
<body>
<script>
// 깊은 복사를 할 수 있는 함수
// concat, filter, map, slice, 스프레드(전개) 연산자
console.log('1. ------------- 스프레드 연산자 ------------- ');
const a = [1, 2, 3];
const b = [...a]; // 스프레드 연산자
b.push(4); // b의 데이터를 변경하였다. 깊은 복사라면 a의 데이터가 달라져서는 안된다.
console.log(`a의 값은 : ${a}`); // 1,2,3
console.log(`b의 값은 : ${b}`); // 1,2,3,4
console.log('2. ------------- 추가하기 ------------- ');
const a2 = [1, 2, 3];
const b2 = a2.concat(4);
console.log(`a2의 값은 : ${a2}`); // 1,2,3
console.log(`b2의 값은 : ${b2}`); // 1,2,3,4
// a2.push(4); 의 결과는 4
const c2 = [...a, 4];
const d2 = [0, ...a, 4];
console.log(`c2의 값은 : ${c2}`); // 1,2,3,4
console.log(`d2의 값은 : ${d2}`); // 0,1,2,3,4
console.log('3. ------------- 걸러내기 ------------- '); // 삭제할 때 사용한다.
const a3 = [1, 2, 3];
const b3 = a3.filter((n) => {
return n != 1;
}); // boolean을 리턴받는다. true만 가져온다.
console.log(`a3의 값은 : ${a3}`); // 1,2,3
console.log(`b3의 값은 : ${b3}`); // 2,3
console.log('4. ------------- 잘라내기(삽입) ------------- ');
const a4 = [1, 2, 3];
const b4 = a4.slice(0, 2); // 마지막 인덱스는 직전까지다 포함X
console.log(a4); // [1,2,3]
console.log(b4); // [1,2]
const c4 = [a4.slice(0, 2)];
console.log(c4); // [[1,2]]
const d4 = [...a4.slice(0, 2), 4, ...a4.slice(2, 3)];
console.log(d4); // [1,2,4,3]
console.log('5. ------------- 반복하기 ------------- ');
const a5 = [1, 2, 3];
// for(let i=0; i<a5.length; i++) console.log(a5[i]);
// const c5 = a5.forEach((n) => { console.log(n); }); 이렇게 해봤자 c5는 null이다. (리턴 안되므로)
const b5 = a5.map((n) => {
return n;
});
// const b5 = [...a5]; 와 동일한 결과
// 깊은 복사이므로 b5와 a5는 다른 레퍼런스이다.
console.log(b5);
</script>
</body>
</html>
이렇게 작성한 코드를 이제 적용시켜 보자
App.js
import './App.css';
function App() {
let list = [1, 2, 3];
return (
<div>
<div>
{list.map((n) => (
<h1>{n}</h1>
))}
</div>
</div>
);
}
export default App;
forEach는 리턴이 안되므로 map으로 작성해야 화면에 표시된다.
태그 사이의 n을 변수취급 하기 위해 {}로 작성한다.
실행결과 )

'자바 스프링 > react & springboot' 카테고리의 다른 글
#4 React useEffect, useMemo, useRef (0) | 2023.02.12 |
---|---|
#3 React useState (0) | 2023.02.11 |
#1 React 실행흐름, 기본문법 (0) | 2023.01.19 |
#0 React 설치 및 세팅 (0) | 2023.01.18 |