[#set함수의 초깃값 타입]Type error: Type 'Dispatch < SetStateAction>' is not assignable to > type '() => void'. TS2322

"자식에게 전달한 함수 props의 타입을 정의하는 중 발생한 에러"

다음과 같은 에러를 만났습니다

Type error: Type 'Dispatch < SetStateAction>' is not assignable to > type '() => void'. TS2322

어떤 생각으로 코드를 작성했나요?

부모, Router.tsx

...중략...

const [email, setEmail] = useState('');
const [password, setPassword] = useState('');

...중략...
<Route
    path="/test"
    element={
      <Test
        title="Login"
        setEmail={setEmail}
        setPassword={setPassword}
        handleAction={() => handleAction(1)}
      />
     }
/>

자식, Test.tsx

interface lProps {
  title: string;
  setEmail: () => void;
  setPassword: () => void;
  handleAction: () => void;
}

다음의 내용이 생각났습니다.

  1. 함수(setEmail,setPassword,handleAction)을 보내기 때문에, 자식에서 props의 타입을 함수 타입(()=> void)으로 정의해야겠다는 점

  2. email, password, handleAction에 매개변수로 들어갈 값이,
    처음에는 값이 없기 때문에,
    즉 null,undefined이기 때문에,
    전달 할 값이 없어, 비어있는 형태로 보내면 된다 생각한 점


에러의 핵심은 무엇인가요?

다음의 4가지 부분입니다.

const [user,setUser] = useState('')

1. 전달 매개변수의 타입을 정의하지 않은 것

2. set000함수(setUser)는 초기값(user)을 "사용"하는 함수라는 점을 잊은 것

=> 리액트는, 타입스크립트는 setUser함수를 보면 "user는 어떻게 할껀데" 라고 생각한다

3. set000함수(setUser)는 초기값(user)을 "사용"하는데, 사용하는 변수(user)의 타입을 지정하지 않은 점

4. 매개변수의 값이 없는 것과 매개변수의 타입을 고려하는 것은 "다른 문제"임을 아는 것

리액트 타입스크립트에서는 set00함수의 타입을 "Dispatch"라고 정의합니다.

type Dispatch = (value: A) => void;

즉 전달하는 매개변수의 타입을 정의해야 합니다.

const [user, setUser] = useState('')

setUser함수는 user를 (매개변수로) 이용해 새로운 값으로 "set" 하는 함수입니다.

즉, user를 사용하기 때문에, 어떤 user의 타입을 전달하는것인지 정의해야합니다.

다음의 링크를 통해서 해결했습니다.

https://stackoverflow.com/questions/54575523/issue-with-passing-hook-to-child-typescript

여기를 클릭하면 이동합니다.

어떤 코드를 작성하면서 에러가 발생했나요?

코드는 Router.tsx -> Test.tsx-> Form.tsx 순으로 함수 props를 전달하고 있습니다.

1. Router.tsx


...중략...

const [email, setEmail] = useState('');
const [password, setPassword] = useState('');

...중략...
<Route
    path="/test"
    element={
      <Test
        title="Login"
        setEmail={setEmail}
        setPassword={setPassword}
        handleAction={() => handleAction(1)}
      />
     }
/>

2. Test.tsx

import Form from '../Components/Common/Form';

interface lProps {
  title: string;
  setEmail: () => void;
  setPassword: () => void;
  handleAction: () => void;
}

const Test = ({ title, setEmail, setPassword, handleAction }: lProps) => {
  return (
    <div>
      <Form
        title={title}
        setEmail={setEmail}
        setPassword={setPassword}
        handleAction={handleAction}
      />
    </div>
  );
};

export default Test;

3. Form.tsx

import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';
import Button from './Button';
export default function BasicTextFields({
  title,
  setPassword,
  setEmail,
  handleAction,
}) {
  return (
    <div>
      ...중략 ...
    </div>
  );
}

어느코드에서 에러가 발생했나요??

Test.tsx

자식 컴포넌트의 인터페이스, lProps

interface lProps {
  title: string;
  setEmail: () => void;
  setPassword: () => void;
  handleAction: () => void;
}

어떤 코드로 에러를 해결했나요?

interface lProps {
  title: string;
  setEmail: (email: string) => void;
  setPassword: (password: string) => void;
  handleAction: (id: number) => void;
}

자식, Test.tsx에서 props로 받는 함수의 매개변수의 타입을 지정했습니다.

setEmail이란 함수는 email을 value를 set하는데, 이용되는 email의 타입을 string으로,
setPassword에서 password는 string으로,
handleAction에서 id는 number로,

좋은 웹페이지 즐겨찾기