[TIL / React] useState로 배열이나 객체를 관리할 경우

알락·2022년 10월 14일
0

React

목록 보기
3/4

react logo

문제 확인

useState로 배열과 객체를 관리하고 할 때가 있다. 하위 컴포넌트의 체크 여부를 한꺼번에 관리한다거나 복잡한 자료를 객체로 정리해서 하위 컴포넌트에 props로 넘겨주고자 할 수도 있다.
useStatePrimitive Type원시 자료형을 관리할 때는 문제가 없다. 값이 바뀌면 리액트에서는 state의 수정이 있었음을 인지하고 관련된 컴포넌트의 수정사항을 렌더링 한다.
하지만 배열이나 객체형식의 Reference Type, 즉 참조 자료형은 어떻게 인지를 할까?

예시

import React, {useState} from "react";

function App(){
    const [arr, setArr] = useState([]);

    const clickHandler = ()=>{
        setArr(prevArr=>{
            prevArr.push(prevArr.length + 1);
            return prevArr;
        })
        // setArr([...arr, arr.length+1]);
      	// 기존의 작성된 코드를 주석처리하고 이 주석을 지우면 잘 작동합니다.
    }

    const checkHandler = ()=>{
        console.log(arr);
    }

    return (   
        <div>
            <button onClick={clickHandler}>Add Array</button>
            <button onClick={checkHandler}>Check Array</button>
            <ul>
                {arr.map(ele => {
                    return <li key={ele}>{ele}</li>
                })}
            </ul>
        </div>
    )
}

export default App;

간단한 웹앱을 만들어주었다. arr이라는 배열 State를 만들어주었다. "Add Array" 버튼을 누르면 숫자를 1부터 차례대로 배열에 추가한다. "Check Array" 버튼을 누르면 현재 arr배열의 상태를 console로 확인할 수 있다.
우리는 clickHandlersetArr의 사용을 확인해야 한다. 우선 활성화되어 있는 코드문을 살펴보겠다. prevArr로 이전 상태의 arr을 가져온다. arr에 직접적으로 push함수를 사용하여 새로운 숫자를 넣어준다. 그리고 해당 배열을 리턴하여 arr에 저장하였다.
렌더링이 잘 되고 있을까? 다음과 같이 작동이 잘 안되고 있음을 알 수 있다.
example fail
그리고 주석이 되어 있었던 부분의 코드를 활성화하고, 기존 코드 작성문을 주석처리하고 난 이후에 작동화면이다. 활성화되는 코드는 arrspread 처리해주고, 새로운 숫자와 같이 새 배열에 넣어주었다.
example pass

리액트 상태 변화 인식

React는 원래 State값과 Props의 값이 변화했을 때, 해당 값과 관련되어 있는 엘리먼트들만 리렌더링 해주는 방식으로 UI 화면을 제공한다.
하지만 처음 우리가 확인했던 방식으로는 배열의 변화를 React가 인식하지 못하고 있는 것처럼 보인다. React 공식문서에서도 useState의 설명 중 이런 문제에 대해서 설명하고 있다.
React Note 출처 : React 공식문서

비단 배열만이 아닌 객체도 똑같은 문제가 발생하고 있음을 알 수 있다.
내가 추측하기에는 state의 참조값, 즉 메모리 주소가 바뀌어야 React에서 값의 변경이 일어났다는 것을 인지하는 것 같다. 이 때문에 배열이든, 객체이든 useStateset함수를 통해 저장된 요소를 바꾸려고 한다면 새로운 배열이나 객체를 반환해줘야 한다는 것을 알고 있어야겠다.

profile
블록체인 개발 공부 중입니다, 프로그래밍 공부합시다!

0개의 댓글