문제상황 : 자식 컴포넌트에서 부모 컴포넌트로 string[] 타입의 데이터를 상태 끌어올리기를 활용하여 구현하고 있는 도중에 not a function error가 콘솔에 표시되면서 페이지 전체의 렌더링이 되지 않음
추론1. 내가 아직 자바스크립트의 인터프리팅 체계에 대한 이해가 부족해서 당연한 메서드를 잘못된 위치에서 호출하고 있는 것은 아닐까?
=> 문제가 위치한 레이어 : 단위 함수
추론2. 타입의 설정이 잘못되어 있는 것은 아닐까?
=> 문제가 위치한 레이어 : 인터페이스 타입 설정
추론3. 부모 컴포넌트와 자식 컴포넌트의 Props 전달과정 혹은 타입 정의 과정에서 각자 다른 타입/함수를 사용한 경우 타입 추론에 의해 자식 컴포넌트에서 함수로 인식하지 않을 수도 있지 않을까?
=> 문제가 위치한 레이어 : 부모 컴포넌트의 상태변경함수 사용 함수
결론, 추론 2번이 정답!
import { useState } from "react";
import { TagsInput } from "react-tag-input-component";
import styled from "styled-components";
interface PropsType {
setTags: (tags: string[]) => void;
}
const NewTagInput = ({ setTags }: PropsType) => {
const [selected, setSelected] = useState<string[]>([]);
setTags(selected);
return (
<TagInputWrapper>
<TagsInput
value={selected}
onChange={setSelected}
name="tags"
placeHolder="기술 스택을 입력해주세요"
/>
</TagInputWrapper>
);
};
const TagInputWrapper = styled.div`
display: block;
`;
export default NewTagInput;
추론1 : 자식 컴포넌트의 이벤트 핸들링 함수 구조 변경
import { useState } from "react";
import { TagsInput } from "react-tag-input-component";
import styled from "styled-components";
interface PropsType {
setTags: (tags: string[]) => void;
}
const NewTagInput = ({ setTags }: PropsType) => {
const [selected, setSelected] = useState<string[]>([]);
// 타입은 나중에 다시 설정해줘도 되니, 일단 any로 두고 동작여부 및 데이터 전달만 체크!
const handleOnChange = (e: any) => {
console.log(e)
setSelected(e);
setTags(selected);
};
return (
<TagInputWrapper>
<TagsInput
value={selected}
onChange={handleOnChange}
name="tags"
placeHolder="기술 스택을 입력해주세요"
/>
</TagInputWrapper>
);
};
const TagInputWrapper = styled.div`
display: block;
`;
export default NewTagInput;
이렇게 변경하니 결국 동일하게 "Uncaught TypeError: setTags is not a function" 에러가 뜬다.
그럼 결국 타입 에러일 가능성이 높다! (쥔장..)
2. 타입의 설정이 잘못되어 있는 것은 아닐까?
interface PropsType {
setTags: (tags: string[]) => void;
}
참고자료 : https://whoyoung90.tistory.com/45
* 현재 설정한 코드는 다음과 같이 동작한다.
1. tag라는 변수로 정의된 (실제 코드에서는 다른 변수명을 사용해도 상관없다.) 어떤 값을 인자로 전달받는다
2. tag는 string 타입으로 구성된 요소들이 들어있는 배열이다.
3. 이 함수는 인자을 전달받아서 내부 로직을 돌릴 뿐, 별도의 return 값을 지정하지 않는다.
why? useState는 상태변수에 할당하는 내부 로직이 setState 함수 내부에 들어있기 때문이다.
이 생각대로 + 구글링에 나와있는대로 작성했더니 "not a function" 에러가 떴다.
그렇다면 setState를 인자로 전달할 때는, 어떻게 전달할지 또 구글링 + 코드에 밑줄을 일일이 hover해 봤다.
헤헷,, 이미, 내가 할 행동에 대한 타입을 너는 추론하고 있었구나..
interface PropsType {
setTags: React.Dispatch<React.SetStateAction<string[]>>;
}
추가적인 구글링과 학습을 통해 이렇게 코드를 수정했더니! 잘 동작한당!
React.Dispatch<React.SetStateAction<string[]>>
1. React.Dispatch<> : React 클래스 내부에서 어떤 값을 업데이트 하고자 할 때, 사용할 수 있는 제네릭 타입
(내부에 여러 타입들이 변수처럼 재할당 가능한 형태로 정의되어 있음)
2. React.SetStateAction<> : 값를 업데이트 할 때, React에서 자체적으로 정의한 여러 메서드들 중에 setState를 업데이트 할 때 사용하는 제네릭
3. <String[]> : String 요소로 구성된 배열들이 setState에 들어갈 수 있다. === state는 string 요소로 구성된 배열이다.
* (tags : <string[]>) => void 와의 차이
- 그냥 인자로 문자열 요소들로 구성된 배열을 받는다 빼고는 다 다름!
- 특히 내가 오해했던 부분은 setState의 내부로직을 완전히 까본게 아니기 때문에 인터프리팅 과정에서 어떤 지점에서 버그가 등장할 지 알 수 없음!
- 따라서, 반드시! 이미 정의된 타입이 있는지 점검할 필요가 있음! Why? 시간을 줄일 수 있음! + 타입스크립트의 추론을 200% 활용하장!
'프레임워크&라이브러리 > React.js' 카테고리의 다른 글
React-Quill을 활용한 구현 예제 (0) | 2023.04.16 |
---|---|
React-quill을 활용한 구현 예제 (0) | 2023.04.13 |
(Rich-TextEditor) React-quill (0) | 2023.04.12 |
(SPA) React-Router-Dom (0) | 2023.03.06 |
UseRef() (0) | 2023.02.22 |