계발하는 개발자

[Redux/Redux-persist] Warning: Prop `src` did not match 에러 해결 본문

❗️Error

[Redux/Redux-persist] Warning: Prop `src` did not match 에러 해결

dev_genie 2023. 10. 17. 18:58

참고

https://github.com/vercel/next.js/issues/10608

 

에러

redux-persist로 localstorage에 저장한 state값을 값을 유지되게 하려고 했는데

기대와 달리 새로고침 후에 아래와 같은 에러가 났다.

"Prop `src` did not match"

직역하면 속성 'src'가 일치하지 않는다는 에러였다.

 

문제의 img요소 src를 확인해보니 문자열 안에 "" 기호가 한 번 더 들어가 있었다.
그리고 alt 속성값도 "Queencard" 이렇게 깨져있었다..
이때 로컬호스트에 저장된 값이 뭔가 달라졌음을 직감했다.

 

아니나 다를까 이런 식으로 문자열 값 안에 \\ 기호가 새로고침할때마다 들어갔다.

 

원인

결론적으로 PersistGate로 루트 컴포넌트 랩핑하는 것과 중복 이스케이핑되는 문제가 원인이었다..!


redux-persist를 사용할 때 일반적으로 저장된 상태를 JSON 문자열로 직렬화(serialize)하고, 가져올 때는 자동으로 JSON 파싱 처리된다는 사실을 몰랐어서
임의로 'persist:root' KEY로 저장되는 값을 JSON.parse 해줬는데 이렇다보니 이중 이스케이핑 적용이 된거였다.
그래서 해당 src로 저장된 이미지 경로를 찾지 못해 에러를 뱉어낸거다.

 

 

그리고 초기에 root 컴포넌트를 PersistGate로 감싸지 않았었는데

redux-persist에서 PersistGate를 사용하지 않으면, 애플리케이션 초기 렌더링 시에 로컬 스토리지에서 상태를 로드하고 적용하는 기능이 활성화되지 않는다고 한다.

 

해결

PersistGate import 후 루트 컴포넌트를 PersistGate로 감싸줬고

"use client" 
import { Provider } from "react-redux"; 
import "../app/globals.css";
import { store, persistor } from "../ts/store"; 
import { PersistGate } from "redux-persist/integration/react";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        <Provider store={store}>
            <PersistGate loading={null} persistor={persistor}>
                {children}
            </PersistGate>
        </Provider>
      </body>
    </html>
  )
}

 

로컬호스트 데이터 파싱해오는 코드도 지워버렸다.

 

그리고 로컬호스트에 기존에 저장돼있던 값도 삭제해준다.

(로컬호스트에 저장된 값을 들고 나오기 때문에)

 

그러고나서 DOM로드 후 데이터 전달 요소 선택 > 새로고침하면

아래처럼 값이 날아가지 않고 로컬스토리지에 저장된 기본값을 바탕으로 state 상태가 유지된다.

 

😘  결과 화면

LIST
profile

dev_genie

@dev_genie

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!