당근먹는하니
귀엽고 행복해
당근먹는하니
전체 방문자
오늘
어제
  • 분류 전체보기 (274)
    • 다람쥐🐿 (26)
    • C++ 공부빵야 (7)
    • 공부👻 (5)
    • 프론트엔드✏️ (228)
      • 코드캠프 (120)
      • 팀 프로젝트✨ (31)
      • 개인공부 (67)
    • 프론트엔드 - 바닐라js (7)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 공통 컴포넌트
  • algorithm
  • ssg
  • 팀 프로젝트
  • 회고
  • HTML
  • 배열
  • 자바스크립트
  • 부트캠프
  • 코딩
  • emotion
  • 팀프로젝트
  • javascript
  • graphql
  • CSS
  • JS
  • 프로그래머스
  • refreshtoken
  • 프론트엔드
  • react
  • 팀플
  • React-hook-form
  • 알고리즘
  • next.js
  • 코드캠프
  • 리액트
  • 배포
  • javascrpit
  • typescript
  • 코딩 부트캠프

최근 댓글

최근 글

티스토리

250x250
반응형
hELLO · Designed By 정상우.
당근먹는하니

귀엽고 행복해

[react] 회고페이지) 배열 로컬스토리지 복원, 초기화 문제 배열 상태관리, setState / useEffect
프론트엔드✏️/개인공부

[react] 회고페이지) 배열 로컬스토리지 복원, 초기화 문제 배열 상태관리, setState / useEffect

2024. 12. 19. 22:00
728x90
반응형

 

회고 페이지를 만드는데 답을 배열로 받는 질문만 로컬스토리지 복원이 잘 안되는 문제가 생겼다. 

 

1. console.log를 찍어 보면, 로컬스토리지에서 데이터를 잘 복원하고 setAnswer3로 상태를 업데이트한다. 그런데 그 직후, answer3가 다시 ["", "", ""]로 초기화된다.

 

2. answer1과 answer2 같은 문자열 상태에서는 이런 일이 없었음. 왜 배열만 이런 일이?

 

 

리액트 DOM 렌더링 순서 

 

  1. useState 초기값 적용
    • 컴포넌트가 처음 렌더링될 때, useState로 설정된 초기값이 DOM에 반영된다.
    •  이 코드에서 초기값 ["", "", ""]가 DOM에 먼저 반영된다.
    • const [answer3, setAnswer3] = useState(["", "", ""]);
  2. useEffect 실행
    • 첫 번째 렌더링이 완료된 후, useEffect가 실행되면서 로컬스토리지 데이터를 복원한다.
    • 복원된 값으로 setAnswer3를 호출하면 상태가 업데이트되고, 컴포넌트가 재렌더링된다.
  3. 로컬스토리지 값 덮어쓰기
    • 복원된 상태 값(answer3)이 변경되면, useEffect에서 이를 로컬스토리지에 저장한다.
    • 문제는, 초기값 ["", "", ""]도 로컬스토리지에 저장될 수 있다는 것. answer이 변경되면 로컬스토리지에 저장하는 의존성 배열이 있는 useEffect 가 실행되어 자꾸 "", "", "" 로 저장되는 것이었음.. 
// 원래 코드 

  useEffect(() => {
    localStorage.setItem("answer1", answer1);
    localStorage.setItem("answer2", answer2);
	localStorage.setItem("answer3", answer3);
  }, [answer1, answer2, answer3]);

 

(문제가 왜 answer3(배열) 에서만 생기냐고,,, )

  1. answer1, answer2는 문자열(string)
    • 문자열은 값형 데이터(primitive type)라서 상태 변경 시 값 자체가 대체된다.
    • 문자열 상태에서는 초기값 덮어쓰기가 상대적으로 간단하다.
  2. answer3은 배열(array)
    • 배열은 참조형 데이터(reference type)라서 상태를 변경할 때 반드시 새로운 참조를 생성해야 한다.
    • React는 참조를 기준으로 상태 변경을 감지하므로, 참조가 유지되면 상태 변경을 제대로 인식하지 못하거나, 의도치 않게 초기화 로직이 중복될 수 있다.

(배열은 불변성 - 알맹이 그대로 두고 새 배열을 만들어서 참조를 바꾸는 식으로 사용함)

 

 

 

해결방법

 useEffect(() => {
    localStorage.setItem("answer1", answer1);
    localStorage.setItem("answer2", answer2);

    if (answer3 && answer3.some((val) => val.trim() !== "")) {
      localStorage.setItem("answer3", JSON.stringify(answer3));
    }
  }, [answer1, answer2, answer3]);

 

 빈 배열은 저장하지 않기

 

  • 배열 answer3에 값이 하나도 없으면 로컬스토리지에 저장하지 않는다.
  • 배열 안에 하나라도 비어 있지 않은 값이 있을 때만 저장하도록 조건을 건다.

 

이제 "", "", "" 로 초기화된 상태에선 

굿!

 

728x90
반응형
저작자표시 비영리 동일조건 (새창열림)

'프론트엔드✏️ > 개인공부' 카테고리의 다른 글

[Next.js] [MongoDB] CRUD의 Create, Read 연결하기  (0) 2024.05.06
[flutter] 설치부터 난관.  (1) 2024.02.24
[firebase] Firebase 이메일 중복확인  (0) 2023.07.28
gyp ERR!  (0) 2023.04.07
[git]  (0) 2023.04.06
    '프론트엔드✏️/개인공부' 카테고리의 다른 글
    • [Next.js] [MongoDB] CRUD의 Create, Read 연결하기
    • [flutter] 설치부터 난관.
    • [firebase] Firebase 이메일 중복확인
    • gyp ERR!
    당근먹는하니
    당근먹는하니

    티스토리툴바