• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 Next.js 게시판 setState시 다른 상태값도 같이 변합니다.

setState시 다른 상태값도 같이 변합니다.

5 글 보임 - 1 에서 5 까지 (총 5 중에서)
  • 글쓴이
  • #107251

    이창민
    참가자
    게임 친구 목록을 서버로 부터 가져오고, 리셋 버튼을 클릭하면 친구 목록을 초기화 시키기 위해서(친구 정보를 수정할 수 있거든요) 아래와 같이 코드를 작성하였습니다.
    const [friendList, setFriendList] = useState([]);
    const [friendListForReset, setFriendListForReset] = useState([]);
    useEffect(() => {
    instance.get(`/summoner`, {params: {firstConnection,},})
    .then((res) => {
    if (res.data.code === 200) {
    const data = res.data.result
    setFriendList([...data]);
    setFriendListForReset([...data]);
    }
    })
    }, []);
    
    이떄 friendList, setFriendListForReset의 값은 콘솔찍어보면 아래와 같습니다.
    [
        {
            "no": 223,
            "created_at": "2023-12-18 14:28:45",
            "nickname": "강철 우엉#KR1",
            "tier": "DIAMOND",
            "rank": 2,
            "wins": 33,
            "losses": 25,
            "main_position": "tmp",
            "icon_id": 6455,
            "renewaled_at": "2023-12-18 14:28:45",
            "mmr": 27,
            "level": 181,
            "icon_img_url": "https://ddragon.leagueoflegends.com/cdn/13.24.1/img/profileicon/6455.png",
            "from": "friend"
        },
        {
            "no": 225,
            "created_at": "2023-12-18 14:28:59",
            "nickname": "E크에크파이크#KR1",
            "tier": "EMERALD",
            "rank": 2,
            "wins": 123,
            "losses": 126,
            "main_position": "tmp",
            "icon_id": 907,
            "renewaled_at": "2023-12-17 23:28:41",
            "mmr": 23,
            "level": 64,
            "icon_img_url": "https://ddragon.leagueoflegends.com/cdn/13.24.1/img/profileicon/907.png",
            "from": "friend"
        }
    ]
    
    또한 selectBox라는 컴포넌트에서 setFriendList를 실행합니다.
    실행되는 함수는 다음과 같습니다.
    
    const onChangeHandler = (event) => {
    const selectedMmr = event.target.value;
    const selectedTier = options.find(
    (option) => option.mmr === event.target.value,
    )?.tierString;
    const [tier, rank] = selectedTier.split(" ");
    const newFriendList = friendList.map((v) => {
     if (v.nickname === nickname) {
      v.mmr = selectedMmr;
      if (selectedMmr === 0) {
        v.tier = null;
        v.rank = null;
          } else {
        v.tier = tier;
        v.rank = rank;
       }
      return v;
     }
    return v;
    });
    setFriendList(newFriendList);
    이렇게 세팅을 해놓고
    리셋 버튼에 아래와 같은 함수를 달아줬습니다.
    const onClickResetHandler = () => {
    console.log("friendList:", friendList);
    console.log("friendListForReset:", friendListForReset);
    setFriendList(friendListForReset);
    };
    <div className={styles.reset_btn_div}>
     <input
     type="button"
     value="리셋"
     onClick={() => {onClickResetHandler()}}/>
    </div>
    리셋 버튼 클릭시
    console.log("friendList:", friendList);
    console.log("friendListForReset:", friendListForReset);의 값이 같은 값이 찍힙니다.
    
    [
        {
            "no": 223,
            "created_at": "2023-12-18 14:28:45",
            "nickname": "강철 우엉#KR1",
            "tier": "UNRANKED", <= 바뀐 부분
            "rank": null, <= 바뀐 부분
            "wins": 33,
            "losses": 25,
            "main_position": "tmp",
            "icon_id": 6455,
            "renewaled_at": "2023-12-18 14:28:45",
            "mmr": "0", <= 바뀐 부분
            "level": 181,
            "icon_img_url": "https://ddragon.leagueoflegends.com/cdn/13.24.1/img/profileicon/6455.png",
            "from": "friend"
        },
        {
            "no": 225,
            "created_at": "2023-12-18 14:28:59",
            "nickname": "E크에크파이크#KR1",
            "tier": "EMERALD",
            "rank": 2,
            "wins": 123,
            "losses": 126,
            "main_position": "tmp",
            "icon_id": 907,
            "renewaled_at": "2023-12-17 23:28:41",
            "mmr": 23,
            "level": 64,
            "icon_img_url": "https://ddragon.leagueoflegends.com/cdn/13.24.1/img/profileicon/907.png",
            "from": "friend"
        }
    ]
    
    제가 원했던 동작은 friendListForReset값은 useEffect안에서 최초 수정된 후, 값을 그대로 유지해서,
    리셋버튼 클릭시 그 값을 이용해서 friendList값을 리셋시키길 바랬습니다.
     
    불변성을 지키기 위해 얕은 복사했는데도 왜 setFriendList하면 friendListForReset값도 바뀌는지 모르겠습니다.
    어떤게 문제일까요
    
    
     
     
     
    #107304

    codingapple
    키 마스터
    리셋누르면 setFriendList([...friendListForReset]) 해봅시다
    #107364

    이창민
    참가자
    그래도 똑같습니다 ㅠㅠ
    지금 문제가
    setFriendList를 하면 friendListForReset 상태도 같이 바뀌는게 문제인것같습니다.
    #107366

    codingapple
    키 마스터
    처음에 데이터가져와서 state에 넣을 때 
    setFriendListForReset( JSON.parse(JSON.stringify(data)) ); 해서 넣어봅시다
    
    #107369

    이창민
    참가자
    와 선생님 됐습니다.
    깊은 복사에 대해서 공부하러 가보겠습니다.
    감사합니다.
5 글 보임 - 1 에서 5 까지 (총 5 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠