reactjs 修复方法:此表达式不可调用,类型“{}”没有调用签名,ts(2349)

ykejflvf  于 2023-02-22  发布在  React
关注(0)|答案(1)|浏览(909)

大家好,我目前在我的登录文件中遇到了一个类型错误,因为我不熟悉typescript,当尝试将来自API的响应设置到handleLogin函数中的用户变量中,用户代表我的上下文时,我得到了这个错误this expression is not callable. Type '{}' has no call signatures.ts(2349)。下面是我的login.tsx和authContext.tsx文件:

登录名.tsx:

function Login() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const [error, setError] = useState('');
  const [showError, setShowError] = useState(false);
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [user, setUser] = useContext(UserContext);

  const handleLogin = (e: any) => {

    e.preventDefault()

    setIsSubmitting(true)

    setError('')

    const genericErrorMessage = 'Something went wrong! Please try again later.'

    fetch('http://localhost:8081/users/login', {

      method: 'POST',

      credentials: 'include',

      headers: { 'Content-Type': 'application/json' },

      body: JSON.stringify({ username, password }),

    })

      .then(async response => {

        setIsSubmitting(false)

        if (!response.ok) {

          if (response.status === 400) {

            setError("Please fill all the fields correctly!")

          } else if (response.status === 401) {

            setShowError(true)
            setError("Invalid username and password combination.")

          } else {

            setError(genericErrorMessage)

          }

        } else {

          const data = await response.json()
          setUser((oldValues: any) => {
            return { ...oldValues, token: data.token }
          })
          workflow.go(Workflow.Tasks)
        }

      })

      .catch(error => {

        setIsSubmitting(false)

        setError(genericErrorMessage)

      })

  }

  const handleKeyDown: React.KeyboardEventHandler<HTMLInputElement> = ({ keyCode }) => {
    setShowError(false);
     if (keyCode === 13) handleLogin();
  };

身份验证上下文.tsx:

import React, { PropsWithChildren, useState } from "react"

const UserContext = React.createContext([{}, () => { }])

let initialState = {
  username: '',
  password: '',
}

const UserProvider = (props: PropsWithChildren<any>) => {
  const [state, setState] = useState(initialState)

  return (
    <UserContext.Provider value={[state, setState]}>
      {props.children}
    </UserContext.Provider>
  )
}

export { UserContext, UserProvider }
piztneat

piztneat1#

在这一行中,我们创建了上下文,并将一个包含空对象的数组和一个返回空对象的函数设置为默认值:

const UserContext = React.createContext([{}, () => { }])

Typescript推断这是您将在此上下文中使用的值的类型,这就是为什么它向您显示错误消息。
然而,这并不是声明上下文的方式,你可以给予它一个有意义的初始值,或者null""[] ...,如果你事先不知道的话,但是如果你做了后者你必须把正确的类型传递给createContext函数。
在您的情况下,它可能是这样的:

interface User {
  username: string;
  password: string;
}

const initialState = {
  username: '',
  password: '',
}

const UserContext = React.createContext<
  [User, React.Dispatch<React.SetStateAction<User>> | null]
>([initialState, null])

// I'd recommend you type children as React.ReactNode
const UserProvider = ({ children }: { children: React.ReactNode }) => {
  const [state, setState] = useState(initialState)

  return (
    <UserContext.Provider value={[state, setState]}>
      {children}
    </UserContext.Provider>
  )
}

export { UserContext, UserProvider }

相关问题