배열인 상태를 업데이트 하는 패턴

zimablue·2023년 7월 22일

react

목록 보기
1/14

setState()를 통해 state를 업데이트할 때 기존의 state값과 새롭게 업데이트할 값이 같다면 react는 state를 업데이트를 하지 않습니다.

당연한 일이지만 만약 state가 배열일 경우 앞의 조건은 신경써야할 부분이 됩니다.


버튼을 클릭하면 배열인 state에 1을 추가하는 코드입니다.
state에 push로 1을 추가했습니다.
1이 추가된 state을 setState를 통해 바꾸어 주었지만 바뀌지 않습니다.

  const [state, setState] = useState(["a", "b"]);

  const addChar = () => {
    console.log(state);
    // ["a", "b"]

    setState((oldState) => {
      oldState.push("c");
      return oldState;
    });

    console.log(state);
    // ["a", "b", "c"]
  };

  return (
    <div>
      <p>{state}</p>
      /* 첫 화면: ab */
      /* 버튼 클릭 후: ab */
      <button onClick={addChar}>add</button>
    </div>
  );

배열에 값을 추가해도 결국 배열 자체는 똑같은 배열이고,
단지 똑같은 배열에 새로운 값이 추가된 것이기 때문입니다.

따라서 배열인 state로 업데이트 해주기 위해서는 기존의 배열에 1이 추가된 새로운 배열을 만들어줘야합니다.

이번 게시글에서는 새로운 배열을 만드는 일반적인 패턴에 관한 내용입니다.



Spread Operator로 추가(adding)


Spread Operator로 기존 배열에서 값들만 새로운 배열에 풀어 놓습니다.
기존의 값들이 풀어진 새로운 배열에 추가하고 싶은 값을 추가합니다.
state를 setState를 통해 추가된 값이 담긴 새로운 배열로 바꿉니다.

function Chars() {
  const [state, setState] = useState(["a", "b"]);

  const addChar = () => {
    // "c"를 추가
    setState((oldState) => [...oldState, "c"]);
  };

  return (
    <div>
      <p>{state}</p>
		/* 첫 화면: ab */
		/* 버튼 클릭 후: abc */
      <button onClick={addChar}>add</button>
    </div>
  );
}



filter()로 삭제(removing)


filter 메서드에서 제거하고 싶은 값과 같지 않은 값들만 모아 새로운 배열을 만듭니다.
state를 setState를 통해 제거하고 싶은 값이 제거된 새로운 배열로 바꿉니다.

function Chars() {
  const [state, setState] = useState(["a", "b"]);

  const addChar = () => {
    // "b"를 제거
    setState((oldState) => oldState.filter((char) => char !== "b"));
  };

  return (
    <div>
      <p>{state}</p>
		/* 첫 화면: ab */
    	/* 버튼 클릭 후: a */
    <button onClick={addChar}>add</button>
    </div>
  );
}



map()으로 전체 업데이트(replacing)


map으로 기존배열의 값들을 변경 후 반환된 새로운 배열을 업데이트 합니다.

function Chars() {
  const [state, setState] = useState(["a", "b"]);

  const addChar = () => {
    // state의 소문자 알파벳을 대문자로 변환
    setState((oldState) => oldState.map((char) => char.toUpperCase()));
  };

  return (
    <div>
      <p>{state}</p>
		/* 첫 화면: ab */
		/* 버튼 클릭 후: AB */
      <button onClick={addChar}>add</button>
    </div>
  );
}

0개의 댓글