如何修复:此表达式不可调用。类型 ‘{}’ 没有调用签名。ts(2349)

huangapple go评论73阅读模式
英文:

How to fix: this expression is not callable. Type '{}' has no call signatures.ts(2349)

问题

以下是您要翻译的内容:

"Hi everyone I am currently facing a type error in my login file as I am not familiar with typescript, when trying to set the response from the api into the user variable inside my handleLogin function and user is represent my context, I am getting this error this expression is not callable. Type ' {} ' has no call signatures.ts(2349).
Here below are my login.tsx and authContext.tsx files:

Login.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();
  };
}

authContext.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 }

希望这些翻译对您有所帮助。

英文:

Hi everyone I am currently facing a type error in my login file as I am not familiar with typescript, when trying to set the response from the api into the user variable inside my handleLogin function and user is represent my context, I am getting this error this expression is not callable. Type &#39;{}&#39; has no call signatures.ts(2349).
Here below are my login.tsx and authContext.tsx files:

Login.tsx:

function Login() {
const [username, setUsername] = useState(&#39;&#39;);
const [password, setPassword] = useState(&#39;&#39;);
const [error, setError] = useState(&#39;&#39;);
const [showError, setShowError] = useState(false);
const [isSubmitting, setIsSubmitting] = useState(false);
const [user, setUser] = useContext(UserContext);
const handleLogin = (e: any) =&gt; {
e.preventDefault()
setIsSubmitting(true)
setError(&#39;&#39;)
const genericErrorMessage = &#39;Something went wrong! Please try again later.&#39;
fetch(&#39;http://localhost:8081/users/login&#39;, {
method: &#39;POST&#39;,
credentials: &#39;include&#39;,
headers: { &#39;Content-Type&#39;: &#39;application/json&#39; },
body: JSON.stringify({ username, password }),
})
.then(async response =&gt; {
setIsSubmitting(false)
if (!response.ok) {
if (response.status === 400) {
setError(&quot;Please fill all the fields correctly!&quot;)
} else if (response.status === 401) {
setShowError(true)
setError(&quot;Invalid username and password combination.&quot;)
} else {
setError(genericErrorMessage)
}
} else {
const data = await response.json()
setUser((oldValues: any) =&gt; {
return { ...oldValues, token: data.token }
})
workflow.go(Workflow.Tasks)
}
})
.catch(error =&gt; {
setIsSubmitting(false)
setError(genericErrorMessage)
})
}
const handleKeyDown: React.KeyboardEventHandler&lt;HTMLInputElement&gt; = ({ keyCode }) =&gt; {
setShowError(false);
if (keyCode === 13) handleLogin();
};

authContext.tsx:

import React, { PropsWithChildren, useState } from &quot;react&quot;
const UserContext = React.createContext([{}, () =&gt; { }])
let initialState = {
username: &#39;&#39;,
password: &#39;&#39;,
}
const UserProvider = (props: PropsWithChildren&lt;any&gt;) =&gt; {
const [state, setState] = useState(initialState)
return (
&lt;UserContext.Provider value={[state, setState]}&gt;
{props.children}
&lt;/UserContext.Provider&gt;
)
}
export { UserContext, UserProvider }

答案1

得分: 1

在这行代码中,您正在创建一个上下文并将一个包含空对象和一个返回空对象的函数作为默认值的数组传递进去:
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])

// 我建议您将 children 类型定义为 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 }
英文:

In this line you're creating context and setting as default value an array containing an empty object and a function that returns an empty object:

const UserContext = React.createContext([{}, () =&gt; { }])

Typescript infers that this is the type for the value you're going to be using in this context, which is why it is showing you the error message.

This is not, however, how you should declare a context. You can either give it a meaningful initial value or just null, &quot;&quot;, []... if you don't know it beforehand, but if you do the latter you must pass the correct types to the createContext function.

In your case it could be something like this:

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

const initialState = {
  username: &#39;&#39;,
  password: &#39;&#39;,
}

const UserContext = React.createContext&lt;
  [User, React.Dispatch&lt;React.SetStateAction&lt;User&gt;&gt; | null]
&gt;([initialState, null])

// I&#39;d recommend you type children as React.ReactNode
const UserProvider = ({ children }: { children: React.ReactNode }) =&gt; {
  const [state, setState] = useState(initialState)

  return (
    &lt;UserContext.Provider value={[state, setState]}&gt;
      {children}
    &lt;/UserContext.Provider&gt;
  )
}

export { UserContext, UserProvider }

huangapple
  • 本文由 发表于 2023年2月20日 00:25:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75501595.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定