[Spread Operator] ...을 이용하여 서로 다른 배열이나 객체를 합치자

2020. 5. 24. 22:52컴퓨터언어/React JS

728x90
반응형

배열 합치기

const fruits = ["apple", "banana", "kiwi"];
const berry = ["strawberry", "blackberry", "grapeberry"];

const fruits = ["apple", "banana", "kiwi", ...berry];

 

객체 합치기

const fullName = {
  fName: "Tom",
  lName: "Cruise"
};

const actor = {
  ...fullName,
  age: 50,
  genre: "Action"
};

*객체를 합칠 때 위에서처럼 ...를 쓰면 fullName의 원소들과 actor의 원소들이 같은 레벨에 위치하게 되지만,

const actor = {
  fName: "Tom",
  lName: "Cruise",
  age: 50,
  genre: "Action"
};

...를 쓰지 않는다면 하위에 위치하게 된다.

const actor = {
  fullName: {
    fName: "Tom",
    lName: "Cruise"
  },
  age: 50,
  genre: "Action"
};

이 Spread Operator는 useState와 Destructuring으로도 코드의 반복이 많은 경우에 빛을 발한다.

예를 들어, firstName, lastName, email을 input으로 받는 UI가 있다면 다음과 같다.

import React, { useState } from "react";

function App() {
  const [contact, setContact] = useState({
    fName: "",
    lName: "",
    email: ""
  });

  function handleInput(event) {
    const { name, value } = event.target;

    setContact(prevValue => {
      if (name === "fName") {
        return {
          fName: value,
          lName: prevValue.lName,
          email: prevValue.email
        };
      } else if (name === "lName") {
        return {
          fName: prevValue.fName,
          lName: value,
          email: prevValue.email
        };
      } else if (name === "email") {
        return {
          fName: prevValue.fName,
          lName: prevValue.lName,
          email: value
        };
      }
    });
  }

  return (
    <div className="container">
      <h1>
        Hello {contact.fName} {contact.lName}
      </h1>
      <p>{contact.email}</p>
      <form>
        <input onChange={handleInput} name="fName" placeholder="First Name" value={contact.fName} />
        <input onChange={handleInput} name="lName" placeholder="Last Name" value={contact.lName} />
        <input onChange={handleInput} name="email" placeholder="Email" value={contact.email} />
        <button>Submit</button>
      </form>
    </div>
  );
}

export default App;

ㄹㄴㅇㄹㄴㅇㄹㄴ위 코드를 보면 setter에 prevValue 인자를 적용했음에도 비슷한 input이 3개라서 if statement의 중복이 심함을 알 수 있다.

 

가만히 보면 3개 조건절 모두 input 태그의 name 속성의 value를 따지고 있으며, 이들은 "순서대로" 되어있다.

따라서 배열과 ...(Spread Operator)를 이용하면 다음과 같이 코드량을 줄일 수 있다.

  function handleInput(event) {
    const { name, value } = event.target;

    setContact(prevValue => {
      return {
        ...prevValue,
        [name]: value
      }
    });
  }

*[name]처럼 배열 안에 key를 넣어주어야 name을 속성으로 갖고 handleInput을 리스너로 갖는 모든 HTML 태그들에 적용시킨다. 배열에 넣지 않는다면, "name"이라는 String 값을 가진 key로 처리하게 된다.

*그리고 setter 안에서는 [name] 대신 event 인자를 사용할 수 없다.

728x90
반응형