이어지는 글
[JS/리액트] Array.from()에 대해서 (1) (tistory.com)
Array.from()
- 첫 번째 인자는 변환할 대상
- 두 번째 인자는 각 배열 요소를 어떻게 변환할지 정하는 함수
1) Array.from()의 문자열 사용
const str = '안녕하세요';
const arr = Array.from(str);
console.log(arr); // ['안', '녕', '하', '세', '요']
문자열을 한 글자씩 떼서 배열로 만드는 방법
문자열도 반복 가능한 객체라서 하나씩 꺼낼 수 있거든!
그래서 Array.from()을 사용하면 문자열의 각 문자를 하나씩 꺼내서 배열로 변환해 주는 거야.
* 하나씩 꺼낼 수 있으면 반복 가능
2) 배열 선언과 동시에 배열의 값들을
매핑( 어떤 규칙을 이용해서 자동으로 값을 넣는 방법 )해서 생성하고 싶을 때
배열을 선언한다는 것은?
const arr = [1, 2, 3]; // 배열을 선언하면서 값을 넣은 거야.
이건 배열을 선언하고, 동시에 1, 2, 3이라는 값을 넣어준 것.
배열의 값들을 매핑해서 생성한다는 것은?
= 배열을 일일이 값을 넣지 않고 어떤 규칙을 이용해서 자동으로 값을 넣는 방법이
바로 배열 선언과 동시에 매핑해서 생성하는 것이라는 뜻
**매핑(mapping)**은 하나의 값을 변환해서 다른 값으로 만드는 것.
여기서 "배열의 값들을 매핑해서 생성한다"는 건
각 배열의 인덱스에 어떤 규칙을 적용해서 값들을 자동으로 채워주는 것을 의미.
예시: Array.from()을 사용한 매핑
const arr = Array.from(Array(10), (el, idx) => {
return idx * 3;
});
console.log(arr); // [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
- 배열을 선언: Array.from(Array(10))은 길이가 10인 빈 배열을 선언한 거야.
- 배열의 값들을 매핑해서 생성: (el, idx) => idx * 3 이 함수가 배열의 각 인덱스 값에 규칙을 적용해.
이 규칙은 인덱스 번호에 3을 곱한 값을 배열에 넣는 거지.
그래서 배열의 각 요소가 자동으로 [0, 3, 6, 9...] 이렇게 만들어진 거야
이 경우, 배열의 값들은 idx * 3이라는 규칙에 따라 자동으로 생성돼.
이렇게 배열을 선언하고 동시에 값들을 매핑해서 자동으로 채우는 방식이 바로 이 코드의 핵심이야.
- 배열을 선언: 길이가 10인 빈 배열.
- 매핑해서 생성: 각 인덱스에 3을 곱한 값을 자동으로 넣음.
코드 분석하기
const arr = Array.from(Array(10), (el, idx) => {
return idx * 3;
});
console.log(arr); // [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
Array(10) 의 의미 =
이 부분은 길이가 10인 빈 배열을 만드는 것..
즉, 10개의 자리가 있는 배열을 만들어 주지만, 아직 숫자나 값은 들어있지 않아.
Array.from()의 사용=☆★
Array.from()을 사용하면, 이 빈 배열을 원하는 값들로 채울 수 있어.
- 첫 번째 인자로는 채우고 싶은 배열(Array(10)) = 변환할 대상 을 넣고,
- 두 번째 인자(콜백함수)로는 각 배열의 요소를 어떻게 변환할지를 결정하는 함수를 넣는 거야.
(el, idx) => idx * 3의 의미 =
이 부분이 배열의 각 요소를 어떤 값으로 바꿀지를 정의하는 함수야.
두 가지 매개변수를 받아:
- el: 각 요소의 값 (지금은 Array(10)이니까 빈 값이야),
- idx: 배열의 인덱스 번호 (0부터 시작해서 9까지).
(idx * 3)
이 함수는 인덱스 번호(idx)를 받아서 3을 곱한 값을 배열의 각 자리에 넣어줘.
그래서 인덱스 0은 0 * 3 = 0,
인덱스 1은 1 * 3 = 3, 인덱스 2는 2 * 3 = 6... 이런 식으로 채워져.
최종 결과 =
const arr = Array.from(Array(10), (el, idx) => {
return idx * 3;
});
console.log(arr); // [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
인덱스에 3을 곱한 값들로 채워진 배열이 만들어짐.
정리:
- Array(10): 길이가 10인 빈 배열을 만들었고,
- Array.from(): 그 빈 배열을 인덱스에 3을 곱한 값들로 채운 거야.
- 그래서 인덱스 번호에 3을 곱한 배열이 결과로 나와: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27].
el 의 쓰임새 ( 사용해준 이유가 뭘까 )
1. el이 하는 역할
Array.from()의 두 번째 인자인 콜백 함수는 배열을 변환할 때,
각 요소와 그 요소의 인덱스를 받을 수 있어.
이 콜백 함수는 두 개의 매개변수를 가질 수 있어:
- el: 배열의 현재 요소 (지금은 값이 없을 수도 있어, 즉 빈 자리).
- idx: 현재 요소의 인덱스 번호.
하지만 중요한 건, **Array.from(Array(5))**나 **Array.from(Array(10))**처럼 배열을 생성할 때,
처음엔 빈 배열을 만들기 때문에 실제로 배열 요소에 아무 값이 없는 상태야.
즉, 네가 작성한 코드에서 el은 실제 값이 없을 때도 그냥 자리를 차지하고 있는 변수야.
그래서 각 인덱스에만 관심이 있는 경우에 el은 그저 자리를 유지하는 역할을 할 뿐이야.
2. 왜 el을 사용하냐?
- 콜백 함수가 배열의 각 요소와 그 요소의 인덱스를 받게 되어 있기 때문에 el을 써줘야 해.
- 하지만, 특정 상황에서는 el이 필요 없을 수도 있어.
- 자바스크립트는 이 콜백 함수가 항상 두 가지 인자를 받을 수 있다고 생각하기 때문에,
- 첫 번째 인자(el)가 비어 있어도 자리만 차지하고 있는 거야.
3. 꼭 el을 써야 하나?
사실 el을 안 써도 돼. 네가 요소 값을 신경 쓰지 않고 오직 인덱스 값만 사용할 때는 el을 무시할 수 있어.
대신 그냥 **_**처럼 관습적으로 쓰이지 않는 변수를 넣을 수 있어:
const arr = Array.from(Array(5), (_, idx) => idx * 10);
console.log(arr); // [0, 10, 20, 30, 40]
여기서 **_**는 "이 값을 쓸 일이 없어요"라는 의미로 자주 사용되는 관습적인 이름이야.
**el 대신 _**를 넣어도 되는 이유는 우리가 실제로는 요소 값이 필요 없기 때문이야.
결론:
- **el**은 배열의 요소를 의미하지만,
- 지금처럼 빈 배열에서 인덱스 값만 사용할 때는 실제 값이 없어서 의미가 적어.
- 관습적으로 첫 번째 인자를 써야 하기 때문에 자리만 차지하는 역할을 하는 거야.
- 만약 요소 값을 사용하지 않는다면 **_**로 바꾸면 돼!
Array.from()은 첫 번째 인자로 배열을, 두 번째 인자로 map() 콜백 함수를 가진다
첫 번째 인자: 배열
Array.from()의 첫 번째 인자는 변환할 대상이야. 주로 배열이나 배열처럼 생긴 것들을 넣어.
여기서 말하는 배열처럼 생긴 것들은 Set, NodeList, 문자열 같은 것들이야.
예를 들어:
const str = 'hello';
const arr = Array.from(str); // 문자열을 배열로 변환
console.log(arr); // ['h', 'e', 'l', 'l', 'o']
여기서 첫 번째 인자 **str**은 문자열인데,
Array.from()을 사용해서 각 글자를 배열로 변환했어.
두 번째 인자: map() 콜백 함수
Array.from()의 두 번째 인자는 각 배열 요소를 어떻게 변환할지 정하는 함수야.
이 함수는 배열의 각 요소를 변환해 새로운 값을 만들도록 도와줘.
이걸 콜백 함수라고 부르는데, map() 함수의 콜백 함수랑 비슷하게 동작해.
예를 들어:
const arr = Array.from([1, 2, 3], (el) => el * 2);
console.log(arr); // [2, 4, 6]
여기서 두 번째 인자로 들어간 콜백 함수는 각 배열 요소에 2를 곱하는 작업을 해줘:
- 배열의 첫 번째 요소인 1에 2를 곱해서 2.
- 배열의 두 번째 요소인 2에 2를 곱해서 4.
- 배열의 세 번째 요소인 3에 2를 곱해서 6.
이렇게 배열을 변환해서 새로운 배열을 만드는 것이야.
쉽게 설명하면:
- 첫 번째 인자는 배열 또는 배열처럼 생긴 것을 넣고,
- 두 번째 인자는 각 요소를 변환할 규칙을 가진 함수를 넣어.
이 함수는 배열의 각 요소를 변환해서 새로운 값을 만들어 주는 거야.
한 가지 더 예시:
const arr = Array.from(Array(5), (el, idx) => idx * 10);
console.log(arr); // [0, 10, 20, 30, 40]
- 첫 번째 인자 Array(5)는 길이가 5인 빈 배열.
- 두 번째 인자 (el, idx) => idx * 10은 각 인덱스에 10을 곱한 값을 넣는 규칙.
이렇게 두 번째 인자로 넣은 함수 덕분에,
배열을 인덱스 값에 10을 곱해서 새로운 값들로 자동으로 채운 거야.
페이지네이션 컴포넌트
코드 분석하기
{/* Page Numbers */}
<ol>
{Array.from({ length: totalPages }, (_, i) => (
<li
key={i}
onClick={() => onPageChange(i + 1)} // 페이지 번호 클릭 시 실행
style={{ cursor: "pointer", fontWeight: currentPage === i + 1 ? 'bold' : 'normal' }}
// 현재 페이지는 굵게 표시
>
<a href="#">{i + 1}</a> {/* 페이지 번호 */}
</li>
))}
</ol>
1. Array.from()으로 페이지 번호 생성
{Array.from({ length: totalPages }, (_, i) => (
Array.from({ length: totalPages }):
여기서 첫 번째 인자로 **{ length: totalPages }**가 들어가 있어.
이건 길이가 totalPages인 빈 배열을 만들겠다는 뜻이야. 즉, 전체 페이지 수만큼 배열을 생성하는 거지.
예를 들어, totalPages가 5면, 길이가 5인 배열이 만들어져.
즉, 페이지가 5개 있다면 페이지 번호 1, 2, 3, 4, 5를 만들려고 하는 거야.
두 번째 인자는 콜백 함수로,
여기서 **(_, i)**는 각 배열의 요소(_)와 그 요소의 인덱스(i)를 의미해.
여기서 요소 값은 필요 없고 **인덱스 값(i)**을 사용해서 페이지 번호를 만들기 때문에 _로 처리한 거야.
(_, i) => (
<li key={i} onClick={() => onPageChange(i + 1)}>
**i**는 인덱스니까, 인덱스 i에 1을 더한 값이 실제 페이지 번호가 돼.
그래서 i + 1을 사용해 각 페이지 번호(1부터 시작)를 만들고,
페이지 번호를 클릭할 때 onPageChange(i + 1) 함수를 호출해서 해당 페이지로 이동하게 돼.
근데 왜 길이가 totalPages인 빈 배열을 만드는 거지?
우리는 totalPages 변수를 통해 전체 페이지 수를 알고 있어.
그럼 이 페이지 수만큼 번호를 만들어야 하는데,
배열을 사용하면 반복문을 통해 쉽게 번호를 만들 수 있어.
Array.from()을 사용해서 totalPages만큼 빈 배열을 만드는 이유는:
각 인덱스가 페이지 번호로 사용될 수 있기 때문이야.
인덱스 값을 이용해서 페이지 번호를 만들기 위해서는 배열의 인덱스가 필요한데,
배열이 없으면 인덱스도 없어.
그래서 배열을 먼저 만들고,
그 배열의 인덱스를 사용해서 페이지 번호를 만드는 거야.
- { length: totalPages }: 여기서 길이가 totalPages인 빈 배열을 만들어.
예를 들어, totalPages가 5면 길이가 5인 배열이 만들어져. ([ , , , , ] 같은 빈 배열) - (_, i): 콜백 함수에서 두 번째 매개변수인 i는 인덱스를 나타내.
이 인덱스를 통해 페이지 번호를 만들 수 있어.
인덱스 i는 0부터 시작하니까, i + 1을 통해 페이지 번호를 1부터 시작하게 하는 거야.
왜 빈 배열을 써야 할까?
배열을 쓰지 않으면, 페이지 번호를 일일이 손으로 적거나
다른 방식으로 동적 생성해야 해.
하지만 배열을 사용하면 자동으로 인덱스를 반복할 수 있기 때문에,
페이지 번호를 쉽게 동적으로 생성할 수 있어.
length: 5 이게 빈 배열인 이유는 요소를 안쓰고 _ 로 대체했기 때문에 빈 배열인 걸까?
length: 5가 빈 배열인 이유는
배열의 요소들이 실제로 값이 없이 "자리만 차지"하고 있기 때문이야.
이와는 별개로 **_**는 단순히 콜백 함수에서 요소를 사용하지 않겠다는 표시일 뿐,
배열이 빈 배열인 것과는 상관이 없어.
{ length: 5 }는 길이가 5인 객체를 의미해.
이 객체는 Array.from()에 의해 배열로 변환되는데,
여기서 중요한 점은 배열의 요소들은 값이 설정되지 않고,
자리가 비어 있는 상태라는 거야.
[ , , , , ] // 요소는 없고, 자리는 다섯 개 있음.
즉, **값이 없는 "빈 배열"**을 만들게 되는 거지.
_의 역할과 빈 배열과의 관계
- **_**는 콜백 함수에서 첫 번째 매개변수인 배열 요소를 가리키는 자리야.
여기서는 실제로 배열에 요소가 없기 때문에(즉, 빈 자리),
요소를 사용하지 않겠다는 의미로 **_**를 사용한 거야. - 즉, 배열이 빈 배열이기 때문에 요소 값 자체는 의미가 없고,
인덱스(i)만 사용해서 페이지 번호를 만들고 있는 거야.
= 정리
- **length: 5**는 길이가 5인 배열을 만들지만,
그 배열은 실제 값이 없고 빈 자리만 있는 상태야.
이것을 **"빈 배열"**이라고 부르는 이유야. - _는 배열의 요소를 사용하지 않겠다는 표현일 뿐,
배열이 빈 상태로 생성된 것과는 상관이 없어.
인덱스(i)만 사용해서 페이지 번호를 만들기 위해서
el 대신 **_**를 사용하는 거야.
결론적으로,
빈 배열이 만들어지는 이유는 length만 주어졌기 때문이고,
_는 그 빈 배열의 요소를 사용하지 않겠다는 의미일 뿐이야.
페이지 번호가 1, 2, 3, 4, 5 로 만들어지는 이유 >>>
Array.from({ length: 5 })
이 코드는 실제로는 [ , , , , ] 이렇게 생긴
빈 배열을 생성해. 이 배열에는 아무런 값도 없고,
자리만 차지 하고 있는 상태야.
그럼 이 배열의 각 자리를 인덱스 라고 부를 수 있어.
**Array.from()**의 두 번째 인자로 들어간 콜백 함수가
어떻게 페이지 번호를 만드는지 알아볼게.
Array.from({ length: 5 }, (_, i) => i + 1)
콜백 함수는 배열의 각 요소에 대해 어떤 값을 반환할지 결정해.
**첫 번째 매개변수 _,**는 배열의 **값(요소)**를 가리키지만,
우리에겐 필요 없으니 그냥 **_**로 무시하고 있어.
**두 번째 매개변수 i**는 인덱스야.
배열에서 인덱스는 0부터 시작해.
(_, i) => i + 1
- **i**는 배열의 인덱스인데,
배열의 첫 번째 요소는 인덱스 0,
두 번째 요소는 **인덱스 1**이야.
그래서 **i + 1**을 하면 인덱스가 0일 때는 1, 1일 때는 2가 돼. - 즉, 인덱스 i에 1을 더해서 우리가 원하는 **페이지 번호(1부터 시작)**를 만드는 거야.
결과
만약 totalPages가 5라면,
**Array.from({ length: 5 }, (_, i) => i + 1)**는 아래와 같이 동작해:
- 첫 번째 인덱스 i는 0이니까, i + 1은 1 → 1번째 페이지 번호
- 두 번째 인덱스 i는 1이니까, i + 1은 2 → 2번째 페이지 번호
- 세 번째 인덱스 i는 2이니까, i + 1은 3 → 3번째 페이지 번호
- 네 번째 인덱스 i는 3이니까, i + 1은 4 → 4번째 페이지 번호
- 다섯 번째 인덱스 i는 4이니까, i + 1은 5 → 5번째 페이지 번호
최종적으로:
[1, 2, 3, 4, 5]
이렇게 1, 2, 3, 4, 5 라는 페이지 번호 배열이 만들어지는 거야.
요약:
**Array.from({ length: totalPages },
(_, i) => i + 1)**는 totalPages만큼의 빈 배열을 만들고,
각 인덱스에 1을 더해서 페이지 번호를 생성해.
이 배열의 각 인덱스는 0부터 시작하니까,
i + 1을 해서 1부터 시작하는 번호를 만들고 있어.
정리:
- 빈 배열이 먼저 totalPages만큼 생기고,
- **콜백 함수의 두 번째 매개변수 i**가 각 자리에 인덱스를 활용해 값을 채워주는 거야.
원래 _ 이게 요소가 들어갈 곳이고 이게 배열을 채워야 되는 것 같 은데,
어떻게 인덱스가 배열을 채울 수 있게 되는 걸까?
1. 콜백 함수의 두 매개변수: el(요소)과 i(인덱스)
Array.from({ length: 5 }, (el, i) => i + 1)
여기서 **첫 번째 매개변수 el**은 **배열의 요소(값)**를 나타내.
즉, 배열에 이미 있는 값이 있으면 그 값이 el에 들어가.
**두 번째 매개변수 i**는 인덱스를 나타내.
배열에서 각 자리가 몇 번째인지를 알려주는 역할을 해.
2. 왜 el(요소)이 아닌 i(인덱스)가 배열을 채우는지
지금 우리가 사용하는 코드는 빈 배열을 만들어서 값이 없기 때문에
첫 번째 매개변수 el(요소)에는 아무 값도 없고, 빈 값이 들어가.
Array.from({ length: 5 }) // [ , , , , ] (빈 배열)
이렇게 빈 배열이기 때문에 el이 실제로는 아무 역할도 하지 않게 되는 거야.
그래서 el은 무시해도 괜찮아.
3. 인덱스를 활용해 배열을 채우는 방법
빈 배열에는 값이 없으니까, 우리는 인덱스 i를 이용해서 배열에 값을 채우는 방법을 사용해.
Array.from({ length: 5 }, (_, i) => i + 1)
- **_**는 배열의 요소(값)를 나타내지만, 값이 없으므로 무시하고 _로 대체.
- **i**는 배열의 인덱스를 나타내니까,
- **i + 1**을 하면 인덱스에 1을 더해서 1부터 시작하는 번호를 배열에 넣을 수 있어.
즉, 배열에 값이 없으니까 요소 대신 인덱스를 이용해서 값을 넣는 거야.
4. 인덱스 i로 배열을 채우는 과정
Array.from({ length: 5 }, (_, i) => i + 1)
- 인덱스 i는 0부터 시작해서 배열의 각 자리를 채워 나가.
- 첫 번째 인덱스 i는 0이니까, **i + 1**은 1 → 첫 번째 자리에 1이 들어감.
- 두 번째 인덱스 i는 1이니까, **i + 1**은 2 → 두 번째 자리에 2가 들어감.
- 이런 식으로 계속해서 인덱스에 1을 더한 값으로 배열을 채워 나가.
최종적으로 **[1, 2, 3, 4, 5]**라는 배열이 만들어져.
정리:
- _는 배열 요소를 가리키지만, 지금은 배열에 요소가 없어서 무시.
- i는 인덱스를 나타내고, 배열의 각 자리를 인덱스 값으로 채움.
- 그래서 배열을 채우는 역할을 인덱스가 하게 되는 거야.
= (_, i) => i + 1: 배열의 **각 인덱스(i)**에 **i + 1**을 계산해서 그 값을 넣음
2. 페이지 번호를 클릭하면 페이지 변경
onClick={() => onPageChange(i + 1)}
이 부분은 페이지 번호를 클릭했을 때 호출되는 함수야.
onPageChange(i + 1): 현재 클릭한 페이지 번호로 이동하기 위해,
페이지 번호를 인자로 받아서 함수 onPageChange가 실행돼.
예를 들어, 3번 페이지를 클릭하면 **onPageChange(3)**이 실행되는 거야.
페이지 번호를 클릭하면 그 페이지로 이동하는 원리
1. onClick과 onPageChange 함수
<li
key={i}
onClick={() => onPageChange(i + 1)} // 페이지 번호 클릭 시 실행
>
<a href="#">{i + 1}</a> {/* 페이지 번호 */}
</li>
이 부분에서 핵심은 onClick 이벤트와 onPageChange 함수야.
onClick={() => onPageChange(i + 1)}:
페이지 번호를 클릭하면
해당 인덱스(i)에 1을 더한 값이 onPageChange 함수에 전달돼.
- 예를 들어, 3페이지를 누르면 i는 2니까 i + 1은 3이 되고,
- 3이 onPageChange 함수로 전달돼.
- 마찬가지로 2페이지를 누르면 **i + 1 = 2**가 전달돼.
2. onPageChange가 하는 역할
onPageChange 함수는 페이지 번호가 변경될 때 실행되는 함수야.
클릭한 페이지 번호를 받아서 **현재 페이지(currentPage)**를 업데이트해.
예를 들어:
function onPageChange(pageNumber) {
setCurrentPage(pageNumber); // 클릭된 페이지 번호로 currentPage를 업데이트
}
- **pageNumber**는 우리가 클릭한 페이지 번호야.
- 만약 3페이지를 눌렀다면 **pageNumber = 3**이 되고,
- **setCurrentPage(3)**을 호출해서 현재 페이지를 3으로 변경해.
3. 어떻게 누른 페이지를 아는지
페이지 번호를 클릭할 때마다
해당 페이지 번호가 onPageChange 함수로 전달되면서,
그 값이 **현재 페이지(currentPage)**로 저장돼.
- 예를 들어, 3페이지를 클릭하면 **onPageChange(3)**이 호출되고,
- **currentPage**가 3으로 업데이트돼.
그 후에 React는 currentPage의 값을 활용해서
현재 보여줘야 할 페이지의 내용을 다시 렌더링해.
4. 과정 정리
클릭 이벤트 발생: onClick={() => onPageChange(i + 1)}로
클릭한 페이지 번호(i + 1)가 onPageChange 함수로 전달됨.
페이지 번호 업데이트: **onPageChange(pageNumber)**가 실행되어,
currentPage가 클릭한 페이지 번호로 변경됨.
페이지 리렌더링: currentPage 값에 따라 해당 페이지의 콘텐츠를 다시 렌더링.
예시:
- 2페이지를 누르면: onPageChange(2) 호출 → currentPage = 2
- 3페이지를 누르면: onPageChange(3) 호출 → currentPage = 3
이 과정에서 React가 페이지 번호에 맞는 화면을 보여주게 되는 거야.
☆내가 누른 페이지가 3페이지인지 2페이지인지를 어떻게 인식하는지 알아보기★
= 사용자가 꼭 순차적으로 페이지를 클릭하지 않아도
i 값이 정확하게 해당 페이지 번호에 맞게 동작하는 이유
사용자가 어떤 페이지를 클릭하든,
그 페이지는 고유한 인덱스 **i**를 가지고 있어.
예를 들어:
- 1페이지는 i = 0 → **i + 1 = 1**이 전달.
- 2페이지는 i = 1 → **i + 1 = 2**가 전달.
- 3페이지는 i = 2 → **i + 1 = 3**이 전달.
i 값은 페이지마다 고정된 인덱스이기 때문에,
사용자가 순차적으로 클릭하지 않더라도
그 페이지 번호에 맞는 i + 1 값이 정확하게 전달되는 거야.
예시 :
만약 사용자가 2페이지를 처음에 클릭했다면,
해당 리스트 항목의 **i = 1**일 거야. (인덱스는 1)
그래서 **onClick={() => onPageChange(i + 1)}**에서 **onPageChange(2)**가 실행돼.
다시 말해,
각 페이지 번호는 정해진 인덱스를 가지고 있고,
사용자가 클릭할 때마다
그 인덱스에 맞는 페이지 번호를 onPageChange 함수에 전달하게 되는 거야.
정리
- i는 배열의 인덱스이고, **i + 1**이 실제 페이지 번호를 의미해.
- 사용자가 어떤 페이지를 클릭하든,
- 그 페이지의 인덱스 i에 맞는 페이지 번호가 **onPageChange(i + 1)**로 전달돼.
- 사용자는 순차적으로 클릭할 필요 없이,
- 어느 페이지를 클릭하든 그 페이지 번호가 정확하게 인식돼.
※ ※ 페이지 숫자를 클릭하는 순간
해당 페이지의 **인덱스(i)**에 +1을 더한 값이
onPageChange 함수에 전달되는 것. ※ ※
다시 정리하면:
**Array.from**을 통해 페이지 숫자 리스트가 미리 만들어져 있어.
예를 들어, 5개의 페이지가 있다면, 인덱스 i는 0부터 4까지 생성돼.
- i = 0 → 1페이지
- i = 1 → 2페이지
- i = 2 → 3페이지 ...
사용자가 2페이지를 클릭하면, 그 페이지는 **i = 1**에 해당해.
그래서 **onClick={() => onPageChange(i + 1)}**에서 **onPageChange(2)**가 실행돼.
onPageChange(2) 함수가 호출되면,
React의 상태가 2페이지로 변경되고,
그에 따라 2페이지에 해당하는 데이터를 가져와서 화면에 보여주게 돼.
즉, 페이지 숫자들은 미리 i + 1로 만들어진 값들이고,
클릭할 때마다 그에 맞는 페이지 번호가 함수에 파라미터(page)로 전달되는 거지!
3. 현재 페이지 스타일 적용
style={{ cursor: "pointer", fontWeight: currentPage === i + 1 ? 'bold' : 'normal' }}
현재 페이지 번호와 currentPage 값이 같으면
굵게(bold) 표시해주는 조건부 스타일이 적용돼.
currentPage === i + 1: 현재 활성화된 페이지와 같은 번호면 fontWeight: 'bold',
그렇지 않으면 **fontWeight: 'normal'**이 적용돼서 현재 페이지가 굵게 표시돼.
4. 각 페이지 번호를 <li>로 표시
<li key={i}>
<a href="#">{i + 1}</a>
</li>
- 각 페이지 번호는 <li> 태그로 감싸져 있어,
- 각 페이지 번호가 리스트로 표시되는 형태야.
key={i}: 리액트에서 **각 리스트 항목에 고유한 key**를 넣어줘야 해서 **인덱스 i**를 key로 사용한 거야.
왜 각 리스트 항목(list 태그)에도 key를 넣어줘야 하나?
<a href="#">: 페이지 번호를 클릭하면 이동할 수 있는 링크처럼 보이도록 <a> 태그로 감쌌어,
페이지 번호는 i + 1을 통해 1부터 시작하는 숫자로 표시되고 있어.
최종 요약:
이 코드는 페이지 번호를 자동으로 생성하고,
페이지 번호를 클릭하면 해당 페이지로 이동하는 기능을 구현한 거야.
**Array.from()**을 이용해서 총 페이지 수만큼 동적으로 배열을 생성하고,
각 페이지 번호에 클릭 이벤트와 스타일을 적용했지
식 제대로 이해하기
- 이 코드는 길이 5짜리 배열을 생성하고,
- 인덱스 i에 1을 더한 값을 각 요소에 넣어줘.
- 결과는: [1, 2, 3, 4, 5]
그럼 i + 2일 경우:
- i는 0부터 4까지니까, **i + 2**는 다음과 같은 값들이 들어가:
- i = 0 → 0 + 2 = 2
- i = 1 → 1 + 2 = 3
- i = 2 → 2 + 2 = 4
- i = 3 → 3 + 2 = 5
- i = 4 → 4 + 2 = 6
그래서 결과는 **[2, 3, 4, 5, 6]**이 돼!
즉, i에 2를 더한 값들이 차례로 배열에 들어가는 것이야. 🙂
'> 메모 > React' 카테고리의 다른 글
[JS/리액트 ] 헷갈리는 인수와 인자 (1) | 2024.10.02 |
---|---|
[리액트] Link와 useNavigate 비교 (0) | 2024.09.27 |
[JS/리액트] Array.from()에 대해서 (1) (1) | 2024.09.21 |
[리액트] props 쉽게 쓰고 싶으면 (0) | 2024.09.05 |
[리액트] Navigate 와 useNavigate 의 차이 (0) | 2024.09.04 |