Today I learn..."Spread Operator"

mr.ginger·2021년 6월 6일
0

최근 프로젝트를 하면서 어려운 문제가 있었기에, 해결 하느라 포스팅이 뜸했다.
이번 포스팅부터는 프로젝트를 해결하면서 어려웠던 점이나, 알면서 잘 사용하지 못했던 요소들을 다룰 예정이다.

우선 먼저, Spread Operator(전개구문)부터 시작하겠다.

Spread Operator

전개구문은 아마, 자바스크립트를 위주로 공부하다가, 리액트로 넘어오게 되면 좀 생소한 개념이 될 수 있다고 생각한다.

자바스크립트를 깊게 공부한 사람이면 다르겠지만, 시작한지 얼마 되지 않아 심도 있는 공부 보다는 주로 사용하는, 사용 되는 기능만을 익혀온 사람에게는 꽤나 생소하게 다가 올 것이다.

핵심만 전달하면, array와 object등의 구조를 깨고, 안의 아이템만을 가져 오는것이다.

간단하게 예를 들어보자면,

const arr1 = ['mon','tue','wed'];
const arr2 = ['thr', 'fri', 'sat'];
const newArr1 = [...arr1];
const newArr2 = [...arr2];

console.log(...newArr1,...newArr2); // 'mon' 'tue' 'wed' 'thr' 'fri' 'sat' 출력

과 같이 들 수 있는데, 이처럼 각 배열의 아이템만들 가지고 오고 싶을때도 사용되고,
다음과 같이 사용 할 수도 있다.

console.log([...newArr1,...newArr2]); // [ 'mon', 'tue', 'wed', 'thr', 'fri', 'sat' ] 출력

처럼 새로운 배열을 만들 수도 있고,

console.log([...newArr1,...newArr2].concat('sun'));
console.log([...newArr1,...newArr2,'sun']);
// 둘다 ['mon', 'tue','wed', 'thr','fri', 'sat','sun'] 출력

처럼 배열에 새로운 값을 더해서 출력하는것도 가능하다.

물론 object에서도 새로운 요소의 추가등에 사용 할 수 있다.

const obj1 = {a: 1, b: 2, c : 3};

const objClone = {...obj1,z: 1};

console.log(objClone) // { a: 1, b: 2, c: 3, z: 1 }

와 같이 나타낼 수 있다.

어떤 문제였나?

문제가 발생한 곳은 기존에 나눠서 state를 관리하다가 모든 state를 최상위 컴포넌트로 끌어올리면서 각각의 데이터에 어떻게 접근해서 데이터를 변경하는가 였다.

코드중 일부를 가져와 보자면,

addComment = feedId => {
    const { userData, defaultInput } = this.state;
    const newComment = {
      id: userData[feedId - 1].comments.length + 1,
      userName: 'asdf',
      text: defaultInput[feedId - 1],
      isLiked: false,
    };
    const newFeedData = userData.map((feeds, index) => {
      return feedId !== index + 1
        ? feeds
        : { ...feeds, comments: feeds.comments.concat(newComment) };
    });

와 같은 코드이다.

아래 컴포넌트에서 props로 값을 받아오고, state의 값에따라 text에 저장해서, 댓글을 추가하는 로직의 일부이다.

이중 Spread Opretor가 적용된 부분을 보면,

    const newFeedData = userData.map((feeds, index) => {
      return feedId !== index + 1
        ? feeds
        : { ...feeds, comments: feeds.comments.concat(newComment) };
    });

여기서 userData는 [ { O,O,O,[o,o,o] }, { O,O,O,[o,o,o] }, { O,O,O,[o,o,o] } ] 와 같은 구조를 가지고 있는 json 데이터를 복사한 값을 state로 가지고 있는 데이터이다.

흐름을 해설하자면 처음 userData에 map()을 사용해 각각의 item과 index를 얻는다.
이때 얻은 값은 3개의 object이고, 이중 feedId와 index+1이 맞지 않으면 그대로 두지만, 값이 일치 한다면 안의 값을 바꾸는 로직이다.

지금은 이것저것 복잡하게 보이지만, 간단하게 바꾸면

const obj1 = {x: 'hello', y: 'goodbye'}
const obj2 = {y: 'world'}
const changed = { ...obj1, y: obj2.y };

console.log(changed); // { x: 'hello', y: 'world' }

이렇게도 간단히 나타 낼 수 있는 로직이다.
다만 데이터의 깊이가 한번에 접근하기 힘든 위치이고, 아직까지 다뤄보지 않은 사용법이라 더 어렵게 느껴졌던것 같다.

다만 이 로직이 처음엔 생각 나지 않았고, 멘토님에게 질문 하고 나서 알게 되었다.
그마저도 블로그를 작성하며 완전히 이해가 가는 느낌이었다.

리액트를 다루면서 바닐라 자바스크립트와 비교해서 가장 큰 차이점은 아마도 이런 배열이나 obj를 다루는 빈도와 심도가 점점 늘어가는것이 아닐까 하는 생각이 들었다.

앞으로 비슷한 문제가 나오면 해결 할 수 있을것 같은 느낌이 든다.

0개의 댓글