• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

타입스크립트 리액트 로컬스토리지 사용 질문

23.12.30 19:18 작성 23.12.30 19:23 수정 조회수 209

2

안녕하세요:) 질문이 있어서 찾아왔습니다 ㅠㅠ...

타입스크립트로 리액트 프로젝트를 할 떄 로컬스토리지를 사용할 경우 문제가 발생하여 질문드립니다.

 

아래코드는 유저와 컴퓨터의 점수를 담고 있는 State입니다.

이 State의 초기값은 로컬스토지리에서 가지고 올 수 있는 값이 없다면 userScore과 computerScore에 숫자 0을 초기값으로 부여하고, 가지고 올 수 있는 값이 있다면 로컬스토리지에서 가지고 옵니다.

  const [score, setScore] = useState<{
    userScore: number;
    computerScore: number;
  }>(
    !JSON.parse(localStorage.getItem("score"))
      ? {
          userScore: 0,
          computerScore: 0,
        }
      : JSON.parse(localStorage.getItem("score"))
  );

 

오류 발생...

아래 코드 부분에서 string | null 형식의 인수는 'string' 형식의 매개 변수에 할당될 수 없습니다. 라는 오류가 발생합니다.

localStorage.getItem("score")

 

getItem을 ctrl + 클릭하여 코드를 들어가 본 결과

  • 반환값? 을 string | null 유니온 타입을 가지고 있습니다.

     

 getItem(key: string): string | null;

 

json.parse에서 parse부분을 ctrl + 클릭하여 코드를 들어가 본 결과

parse에 key값은 string만 받을 수 있게 되어 있습니다.

parse(text: string, reviver?: (this: any, key: string, value: any) => any): any;

 

제 개인적인 의견은 getItem의 반환값 타입이 string | null 이지만 parse에서 key값은 string만 가능하기 때문에 문제가 발생하는 것 같습니다.

 

이 오류를 하루동안 계속 찾아봤는데 정보가 너무 부족했습니다. 그나마 사람들이 말씀하시는 답변의 코드는

JSON.parse(localStorage.getItem("score") || "{}")

 

이렇게 하라고 하셨는데 저 코드를 넣어버리니 로컬스토리지에 value값에 처음으로 담기는 값은 {} 이거였습니다...

 

그래서 저는 다르게 생각해서 `` 와 ${} 이거를 사용하기로 했습니다. 이것도 결국 문자열이라고 배웠기 때문입니다.

let str = `${}`

 

그래서 최종적으로 나온 코드는 아래 코드처럼 바꾸는 거였습니다. 문제 없이 돌아가기는한데 이렇게 써도되는지 의문이 드네요... 혹시 다른 방법이 있을지 궁금합니다.

JSON.parse(`${localStorage.getItem("score")}`)

답변 1

답변을 작성해보세요.

1

안녕하세요 이정환입니다.

localStorage로 부터 꺼내온 데이터는 존재하지 않을 수도 있기 때문에 null과의 union 타입으로 추론됩니다.

그러나 JSON.parse 메서드의 경우 null이나 undefined 값이 인수로 전달되면 런타임 에러를 발생시키기 때문에 localStorage로 부터 꺼내온 값을 아무런 타입 좁히기나 별도 처리 없이 parse에 전달하는 것은 권장되지 않습니다.

따라서 이를 피하시려면 질문하신 방법으로 사용하시거나 조건문을 이용해 localStorage로 부터 불러온 값이 null이나 undefined이 아닐 경우에만 parse를 하시는 걸 추천드립니다.

한상윤님의 프로필

한상윤

질문자

2024.01.01

헉 감사합니다! as string 방법으로 타입 단언을 해도 좋은 방법일까요?

as string은 타입 단언으로써, 실제 캐스팅이 이루어지는게 아닌 눈속임에 불과한 기술입니다. 따라서 코드상의 타입 오류를 지울 수는 있겠지만 향후 발생할 타입 에러를 막지는 못합니다. 그래서 좀 더 견고한 코드를 위해서는 단언보다는 좁히기나 조건문을 이용하심을 추천드립니다.