본문 바로가기

React

리액트(React)의 불변성과 map, filter, concat, slice

자바스크립트의 배열 내장함수에는 push, splice, pop, concat, slice, map, filter 이런것들이 있다.

 

이중에는 push, splice, pop은 원본 배열의 변경하는 녀석들이고,

 

concat, slice, map, filter는 원본 배열을 복사해서 새로운 배열을 만들어내는 녀석들이다.

 

 

리액트에서는 상태(State)를 업데이트할 때 기존 상태를 그대로 두면서 새로운 값을 상태로 설정해야 한다.

 

이를 불변성 유지라고 하는데, 불변성을 유지해주어야 나중에 리액트 컴포넌트의 성능을 최적화 할 수 있기 때문이다.

 

만약 상태를 계속해서 바꿔버리고, 유지시키지 못한다면 VirtualDom을 사용하는 이유도 없고, 리액트의 큰 장점중 하나인 원본과 비교해 변화된 부분만 계산해서 빠르게 랜더링해준다는 점을 취하지 못하게 될 것이다.

 

 

자바스크립트 배열의 map() 함수

 

map 함수는 파라미터로 전달된 함수를 사용해서 배열 내 각 요소를 원하는 규칙에 따라 변환한 후 그 결과로 새로운 배열을 생성해낸다.

 

즉, return 해준다.

 

let arr1 = [1,2,3]

let arr2 = arr1.map((val) => {

  return val * val

})
console.log(arr2) // [1,4,9]

 

좀더 자세히 알아보자면 map 함수의 파라미터는

 

arr.map(callback, [thisArg])

 

이렇게 올수 있다.

 

개발문서 예제에서 [thisArg]처럼 [] 처리가 되어 있는 것은 생략이 가능하다는 의미이다.

 

callback : 새로운 배열의 요소를 생성하는 함수로 다시 3가지의 파라미터를 가질 수 있다.

 - currentValue: 현재 처리하고 있는 요소(배열의 0번째, 1번째, 2번째 인덱스 .. 등등. Iterator처럼 반복을 처리해준다.)

 - index: 현재 처리하고 있는 요소의 index값

 - array: 현재 처리하고 있는 원본 배열

thisArg: callback 함수 내부에서 사용할 this 레퍼런스

 

const numbers = [1, 2, 3, 4, 5]
const result = numbers.map((num, index, arr) => `현재 ${arr}배열의 ${index}번째 요소 처리중 : ` + num * num)

console.log(result);

 

이런 결과를 볼 수 있다.

 

배열을 반복하는 이터레이터같은 녀석이라, 하드코딩을 피할 수 있게 해준다.

 

 

filter 함수를 이용해 배열에서 특정 조건을 만족하는 원소들만 분류(원본 배열의 불변성 유지)

 

const numbers = [1, 2, 3, 4, 5, 6]
const removeThreeAndFour = numbers.filter(number => { return (number !== 3 && number !== 4 ) } );
// 결과:1, 2, 5, 6

 

그냥 3,4를 제거 하고 싶을 뿐인데, splice를 사용하지 않고 filter를 통해 새로운 배열을 만들어서 처리한다.

 

 

 

배열의 특정 범위를 잘라서 보여주려고 할때도 splice 대신 slice를 쓰면 불변성이 유지된다.

 

- slice : 기존 배열은 변하지 않고, 잘려진 배열을 반환
- splice : 기존 배열 변하고, 잘려진 배열 반환

 

또한 배열에 새 항목을 추가 할때 push를 사용하지 않고, concat을 사용하면 불변성이 유지된다.