본문 바로가기

프로그래밍/React

React-TypeScript에서 redux사용시 타입 에러 해결과정 기록

타입 추론 오류 확인

imagePaths변수의 타입으로 인해 map속성을 인식하지 못하는 문제 발견

나만의 트위터 사이트를 React-TypeScript로 만들어보려고 프로젝트를 진행하던 중 게시글을 작성하는 PostForm 컴포넌트를 구현하고 컴파일을 하는 과정에서 위 오류를 맞이하게 되었습니다.

 

이미  TypeScript를 적용하는 과정에서 여러 타입 추론에 대한 주의 표시들을 많이 맞닥뜨려서 해당 부분에 대해서도 타입스크립트 학습을 진행하며 천천히 타입 지정을 해주면서 문제상황을 해결해주고 있는 상태였는데 이번 케이스의 경우에는 아예 프로젝트 진행이 불가능해지는 오류였기 때문에 해당 오류를 해결하는 과정을 기록하기 위해 이 글을 포스팅합니다.

 

화살표 함수 주의표시 발견

map 메소드를 사용할 때 중괄호 + 반환을 사용하지 않아 warning발생

그림 1에서 발견한 문제를 분석하기 위해 map메소드를 사용하는 블록을 확인 중 아예 발견하지 못했었던 주의 표시를 추가로 발견하게 되었습니다.

이 부분에 대해서는 조사를 진행해본 결과 map메서드를 사용하는 과정에서 정확하지 않은 코드 구현 방식을 사용했기 때문이라는 것을 알 수 있었습니다.

이 주의 표시를 해결하기 위해서는 아래 두 방식 중 한 가지를 선택해서 적용해야 합니다.

  1. '() => ()' 형식으로 화살표 뒤를 중괄호가 아닌 소괄호로 감싸주기
  2. 중괄호를 유지하며 return()으로 jsx부분을 감싸주기

조사를 진행하기 전까지는 두 방법에 대해서 큰 성능차이 등이 있다고 생각했습니다.

하지만 공식 문서 등을 통해 확인해본 결과 간단하게 1번의 케이스는 코드가 한 줄 일 경우 간단하게 사용하면 되는 방법이었고, 두줄 이상의 복잡한 코드일 경우 2번 방식을 사용해야 한다는 것을 알 수 있었습니다.

 

  개선을 완료한 코드

<div>
    {imagePaths.map((value) => (
            <div key={value} style={{ display: 'inline-block' }}>
                <img src={value} style={{ width: '200px' }} alt={value} />
                <div>
                    <Button>제거</Button>
                </div>
            </div>

    ))}
</div>

다시 타입 추론 문제로

화살표 함수 문제를 해결한 후 타입 관련해서 원인 파악을 다시 진행했습니다.

 

useSelector를 이용해 state를 불러올 때 imagePaths가 never[]타입으로 인식
컴파일러가 변수의 타입을 void로 추론

imagePaths변수의 타입을 확인해보니 map을 사용할 수 없는 void타입으로 추론 중이라는 것을 확인할 수 있었습니다.

저는 타입 추론 문제를 해결하기 위해서 reducers/post.ts에서 state를 선언했던 부분 위쪽에 인터페이스 선언을 통해 타입들을 지정해 주기로 결정했습니다.

 

interface PostState {
    mainPosts: {
        id: number;
        User: {
            id: number;
            nickname: string;
        };
        content: string;
        Images: {
            src: string;
        }[];
        Comments: {
            User: {
                nickname: string;
            };
            content: string;
        }[];
    }[];
    imagePaths: string[];
    postAdded: boolean;
}

const initialState: PostState = {
    mainPosts: [{
        id: 1,
        User: {
            id: 1,
            nickname: 'William'
        },
        content: '첫 번째 게시글 #해시태그',
        Images: [{
            src: 'https://cdn.pixabay.com/photo/2023/05/27/11/12/naxos-8021321_1280.jpg'
        },],
        Comments: [{
            User: {
                nickname: '답변자',
            },
            content: '샘플 답글',
        }],
    }],
    imagePaths: [],
    postAdded: false,
};

 

여전히 발생하고 있는 에러

코드를 개선해서 string배열로 타입 지정을 해줬음에도 여전히 컴파일러는 imagePaths변수를 void로 인식하고 있는 상태인 것을 발견한 후 다시 밑줄이 쳐져있는 오류 원인에 관심을 집중하게 되었습니다.

Expexted an assignment or function call and instead saw an expression.

 

컴파일러가 친절하게 제시해주는 이 오류 메시지가 이번 케이스를 마무리할 수 있는 실마리라고 생각해 이 부분에 대한 조사를 진행했습니다.

 

결론

useSelector 콜백 함수에 대한 redux 공식 사이트의 문서를 확인하며 오류의 원인을 분석해본 결과 imagePaths state를 불러올 때 중괄호로 묶는 실수로 인해 컴파일러가 state.post.imagePaths의 값을 직접 반환하지 못하게 되고 중괄호로 인해 발생한 함수 블록에 반환값이 없으니 컴파일러는 암시적으로 반환값을 undefined(void유형)으로 인식했다는 것을 알 수 있었습니다.

 

만약 중괄호로 묶었을 때 void가 아닌 원하는 타입이 지정되도록 하려면 map메서드때와 같이 return을 통해 반환값을 명시해줘야 합니다.

 

// imagePaths에 원하는 타입이 들어가도록 처리할 수 있는 두 가지 구현방법
const imagePaths = useSelector((state: RootState) => state.post.imagePaths);
const imagePaths = useSelector((state: RootState) => { return state.post.imagePaths });

후기

이번 오류에 대한 해결 방법을 조사하는 과정에서 아직 React, TypeScript와 충분히 친해지지 않은 상태라는 것을 새삼 깨달을 수 있었습니다.

조금만 더 익숙해진 상태였다면 오류 메시지가 뜻하는 바를 곧바로 깨닫고 불필요한 부분에 대한 조사를 덜 진행했겠지만 이번 케이스를 조사하며 화살표 함수에 중괄호를 이용해 묶을 경우 리턴값을 지정해주지 않으면 예상치 못한 오류가 발생해 헤맬 수밖에 없다는 것을 알 수 있었습니다.

 

비록 간단한 오류였지만 여러 방향으로 조사를 진행하며 오류 원인 분석과 오류 수정작업을 마무리하며 공식 문서에는 필요한 모든 것이 다 있고 내가 찾기 나름이라는 것을 알아갔으며 시간이 날때마다 공식 문서를 탐방하며 이 프로젝트에 적용할 수 있는 좋은 기능이 어떤것이 있는지 확인해볼 생각입니다.

 

 

참고 1: 화살표 함수 - JavaScript | MDN (mozilla.org)

참고 2: https://helicopter55.tistory.com/2

참고 3: https://redux.js.org/usage/usage-with-typescript

참고 4: https://react-redux.js.org/using-react-redux/usage-with-typescript

참고 5: https://redux-toolkit.js.org/tutorials/typescript

참고 6: Hooks | React Redux (react-redux.js.org)

 

 

 

'프로그래밍 > React' 카테고리의 다른 글

기존 React app project에 TypeScript 적용하기  (0) 2022.08.10
React 알아둘 개념  (0) 2019.08.15
리액트 학습  (0) 2019.08.15
React 학습 - Webpack  (0) 2019.07.02