TypeScript 中的 useParams 不允许解构

Posted

技术标签:

【中文标题】TypeScript 中的 useParams 不允许解构【英文标题】:useParams in TypeScript does not allow destructuring 【发布时间】:2021-02-07 13:55:21 【问题描述】:

当我在 this time 时,我正在关注 this video(“JWTUser Sessions with ReactJS & GraphQL...”),这家伙从 react-router-dom 库中解构了 useParams() 方法。

就我而言,这不起作用,因为我收到此错误:

这是此时的全部代码:

import React,  useState, useContext  from 'react';
import  useParams, useHistory  from 'react-router-dom';
import  useConfirmMutation  from '../gql/generated/graphql';
import  AppStateContext  from './provider';

export const Confirm: React.FC = () => 
    const history = useHistory();
    const  appSetAuthToken, appClearAuthToken, gqlError  = useContext(AppStateContext);

    const [show, setShow] = useState(false);
    const [email, setEmail] = useState('');
    const [confirm] = useConfirmMutation();
    const  token  = useParams();

    const handleFormSubmit = async (e: React.FormEvent) => 
        e.preventDefault();

        try 
            setShow(false);
            appSetAuthToken(token);
            const  data  = await confirm( variables: email );
         catch 

        
    ;

    if (token === undefined || token === '')
        return <div>Enlace de confirmación de usuario inválido</div>;

    return (
        <div>
            <div>Página de confirmación de usuario</div>
            show ? <div>gqlError.msg</div> : undefined
            <form>
                <div>
                    <input
                        value=email
                        placeholder='Correo electrónico'
                        type='email'
                        onChange=e =>  setEmail(e.target.value); 
                    />
                </div>
                <button type='submit'>Confirmar</button>
            </form>
        </div>
    );
;

我也在CodeSandbox 上尝试过同样的方法,但它确实有效。不确定,我的错误在哪里。你能看出那个错误吗?

【问题讨论】:

查看类似问题的回复***.com/a/60080307/2206971 我之前没有发现这个问题。因为我在关注视频,所以我没想到会这样。谢谢。 这能回答你的问题吗? required url param on React router v5 with typescript, can be undefined 【参考方案1】:

useParams 是通用的。您需要通过像这样指定泛型的值来告诉打字稿您正在使用哪些参数:useParams&lt;MyParams&gt;();你的情况是:

const  token  = useParams<token?: string>();

其中说tokenstringundefined

【讨论】:

只是好奇,这完全一样吗? const token = useParams&lt;token: string | undefined&gt;(); @apena 技术上是的,实际上不要这样做 @revelt 感谢您的评论。我遇到过同样的问题。您能否详细说明“?”的首选用法?与 "| undefined" 相对的符号? @CodeCody | undefined 表示该属性必须存在,但值可以是undefined? 使属性可选。在这种特殊情况下,您正在解构该对象,它们都会产生相同的影响,即 token 将具有 string | undefined 类型(如果参数实际上不是,则 react-router 类型不会引发任何错误你说的那种类型)。在其他情况下会有所不同,因为 不能分配给token: string | undefined,但可以分配给token?: stringtoken: undefined 可分配给两者。【参考方案2】:

是的,打字稿不能解构像 这样的通用普通对象。 但是any 就像一个魅力。

const  token  = useParams() as any

【讨论】:

这不行。不要简单地使用打字稿在不应该使用的地方使用any。它有它的位置,绝对不是这里。 @Croolman 更明确一点:你应该只在对象真正可以是任何东西时使用any。在这种情况下,我们知道从useParams() 返回的对象将具有哪些属性,这意味着在逻辑上我们知道它不是any 对象。根据经验法则:如果您知道对象将具有哪些属性,则不应使用any。如果您完全了解对象将具有的属性,那么它不应该是any 类型。像这样使用any 违背了使用打字稿的全部目的。

以上是关于TypeScript 中的 useParams 不允许解构的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mapStateToProps 中使用 useParams?

使用 useParams() 钩子获取多个 URL 参数

无法解析符号 useParams

TypeError:使用来自 react-router 的 useParams 时无法读取未定义的属性“匹配”

如何在 axios API 调用中使用“useParams()”?

React Router 的 useParams 导致 useEffect 重新运行